把所有的點分成一個個的置換的循環,對於每一個循環用循環中的最小的數進行置換,但這可能不是最優的。要考慮用循環外的最小數與環內最小數交換後再進行操作,把這兩種都跑一遍,取最小值。
#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;
}