ALDS1_6_D:Minimum Cost Sort (置换群)同POJ 3270

链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_6_D

一个数组构成许多小的闭环(循环链)每个闭环中各个元素交换到自己的位置有两种方法;

1,找当前闭环中的最小值,一直换就好,设闭环中有n个元素,每个元素的价值为wi则交换的代价为(∑wi-min(w1)+(n-1)*min(wi));

2,引入一个值x(x是数组之中的最小值),把x换入之后再换出去,此时交换的代价为(∑wi+n*x+min(wi)+x)

两者取最小即为所求的答案:

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 10010
 
int c[maxn];
 
int main()
{
    int n,ans=0,x=0;
    int a[1010],b[1010];
    bool vis[1010];
    cin>>n;
    for(int i=0; i<n; i++) {
        cin>>a[i];
        b[i]=a[i];
        vis[i]=false;
        x=min(x,a[i]); 
    }
    sort(b,b+n);
    for(int i=0; i<n; i++) 
       c[b[i]]=i;//C数组标识a[i]的值在b[i]中的位置,也就是排序后的正确位置
    for(int i=0; i<n; i++)
    {
        if(vis[i]==true) 
           continue;
        int s=0,mi=maxn,c_len=0;
        int cur=i;
        while(vis[cur]==false)//每一个循环链 
        {
            c_len++;//循环的长度
            s+=a[cur];
            mi=min(mi,a[cur]);//找出min值
            vis[cur]=true;
            cur=c[a[cur]];//循环的下一个元素
        }
        ans+=min(s+(c_len-2)*mi,s+mi+(c_len+1)*x);
    }
    cout<<ans<<endl;
    return 0;}

猜你喜欢

转载自www.cnblogs.com/sweetlittlebaby/p/12643653.html