把所有的点分成一个个的置换的循环,对于每一个循环用循环中的最小的数进行置换,但这可能不是最优的。要考虑用循环外的最小数与环内最小数交换后再进行操作,把这两种都跑一遍,取最小值。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct jq{
long long num;
long long w;
int f;
}mac[50010];
bool cmp(jq x,jq y)
{
return x.w<y.w;
}
int k;
long long n;
long long ma,sum,cnt,mi;
int main()
{
register int i;
scanf("%d",&n);
for(i=0;i<=n-1;i++)
{
scanf("%lld",&mac[i].w);
mac[i].num=i,mac[i].f=0;
}
sort(mac,mac+n,cmp),mi=mac[0].w;
for(i=0;i<=n-1;i++)
{
if(!mac[i].f)
{
cnt=0,sum=0,k=i,mac[i].f=1;
while(i!=mac[k].num)
{
mac[mac[k].num].f=1;
sum+=mac[mac[k].num].w;
k=mac[k].num;
cnt++;
}
ma+=sum+min((cnt*mac[i].w),((cnt+2)*mi+mac[i].w*2));
}
}
printf("%lld\n",ma);
return 0;
}