社区讨论
【违规紫衫】关于最小成本排序
学术版参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lo1hzt9r
- 此快照首次捕获于
- 2023/10/22 21:21 2 年前
- 此快照最后确认于
- 2023/11/02 22:15 2 年前
在阅读《挑战程序设计竞赛2》中有一题(P143),其大致为给定一些货物的重量,每次可以调换两个货物,成本为 (其中 , 为所调换的两个货物, 是货物的重量),问求按升序排序时所需最小成本是多少?(详细题目可以去这)
在书中,它的做法是找要调换的“圆”,即每个点要到达它自己位子所交换所组成的“圆”,一个就是在这个圆中用最小的值不停调换,公式为 ,还有一种就是从所有数中找最小的来调换,公式为 ( 为所有数中最小值),然后代码如下:(这是我自己打的,如果看不惯可以去看看网上的,都是书上的)
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;
}
其中在代码 ~ 行中间那段代码不是很懂,有大佬帮忙看一下吗qwq,万分感谢
回复
共 2 条回复,欢迎继续交流。
正在加载回复...