首页 > 代码库 > poj 3270 Cow Sorting 置换群 简单题

poj 3270 Cow Sorting 置换群 简单题

假设初始状态为 

a:2 3 1 5 4 6

则目标状态为

b:1 2 3 4 5 6且下标为初始状态中的3 1 2 4 5 6(a[3],a[1]...)

将置换群写成循环的形式

(2,3,1),(5,4),6就不用移动了。

移动方式2种

1:选循环内最小的数和其他len-1个数交换

2:选整个序列最小的数和循环内最小的数交换,转到1,再换回来。

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int a[100005],b[100005];
int hash[100005];
bool vis[100005];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+1+n);
        for(int i=1;i<=n;i++) hash[a[i]]=i;
        int ans=0;
        /*
        2 3 1
        1 2 3----id: 3 1 2
        */
        for(int i=1;i<=n;i++)
        {
            if(vis[i]||a[i]==b[i]) continue;
            int id=i,x=a[i],len=0,mins=0x3f3f3f3f,sum=0;
            while(true)
            {
                sum+=x;
                mins=min(mins,x);
                vis[id]=true;
                x=b[id];
                id=hash[b[id]];
                len++;
                if(x==a[i]) break;

            }
            ans+=min(sum-mins+mins*(len-1),(sum-mins+b[1]*(len-1)+2*(b[1]+mins)));
        }
        printf("%d\n",ans);
    }
    return 0;
}