社区讨论

【违规紫衫】关于最小成本排序

学术版参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo1hzt9r
此快照首次捕获于
2023/10/22 21:21
2 年前
此快照最后确认于
2023/11/02 22:15
2 年前
查看原帖
在阅读《挑战程序设计竞赛2》中有一题(P143),其大致为给定一些货物的重量,每次可以调换两个货物,成本为 w[i]+w[j]w[i] + w[j] (其中 ii, jj 为所调换的两个货物,ww 是货物的重量),问求按升序排序时所需最小成本是多少?(详细题目可以去)
在书中,它的做法是找要调换的“圆”,即每个点要到达它自己位子所交换所组成的“圆”,一个就是在这个圆中用最小的值不停调换,公式为 Σw[i]+(n2)min(w[i])\Sigma w[i] + (n - 2) * min(w[i]),还有一种就是从所有数中找最小的来调换,公式为 Σw[i]+min(w[i])+(n+1)x\Sigma w[i] + min(w[i]) + (n + 1) * xxx 为所有数中最小值),然后代码如下:(这是我自己打的,如果看不惯可以去看看网上的,都是书上的)
CPP
//
#define debug
#include <bits/stdc++.h>

using namespace std;

const int Maxn = 1e3 + 1, Maxm = 1e4 + 1;
int n, ans, a[Maxn], s, b[Maxn], t[Maxm]; 
bool f[Maxn];

void dfs(){	//函数没啥别的意思时就喜欢叫dfs,跟深搜没半毛钱关系 
	ans = 0;
	memset(f, 0, sizeof(f));
	for(int i = 1; i <= n; i++){
		b[i] = a[i];
	}
	sort(b + 1, b + n + 1);
	for(int i = 1; i <= n; i++){
		t[b[i]] = i;
	}
	for(int i = 1; i <= n; i++){
		if(f[i]){
			continue;
		}
		int tmp, qwq = i, S = 0, m = Maxm, cnt = 0;
		while(1){
			f[qwq] = true;
			cnt++;
			tmp = a[qwq];
			m = min(m, tmp);
			S += tmp;
			qwq = t[tmp];
			if(f[qwq]){
				break;
			}
		}
		ans += min(S + (cnt - 2) * m, m + S + (cnt + 1) * s);
	}
}

int main(){
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  s = Maxm;
  for(int i = 1; i <= n; i++){
  	cin >> a[i];
  	s = min(a[i], s);
	}
	dfs();
	cout << ans << endl;
	return 0;
}

其中在代码 1818 ~ 3636 行中间那段代码不是很懂,有大佬帮忙看一下吗qwq,万分感谢

回复

2 条回复,欢迎继续交流。

正在加载回复...