poj 3270 Cow Sorting(置换群)

链接:http://poj.org/problem?id=3270


做这道题,是昨天的比赛被1003给虐爆了.


/*
Problem ID: poj 3270
meaning: 给出一列数,要将其排列成升序序列所需的最少花费,ps:cost 是交换的两数之和.
Analyzing:置换群.黑书p248.找到每个循环节的长度ki和它的最小元素ti cost=sum+sum(min(ki-2)*ti,ti+(ki+1)m)
*/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>

using namespace std;
typedef struct even{int y1,y2,x;}even;

#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define LL long long
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 10005
#define maxm 100005

LL gcd(LL a,LL b) {return a?gcd(b%a,a):b;}

int main(){
    int N,m=maxm;
    int A[maxn],B[maxn],hash[maxm],vis[maxn];
    scanf("%d",&N);
    int cost=0;
    FOR(i,0,N){
        scanf("%d",&A[i]);
        B[i]=A[i];
        m=min(m,A[i]);
    }
    sort(B,B+N);
    FOR(i,0,N) hash[B[i]]=i;
    memset(vis,0,sizeof(vis));
    cost=0;
    FOR(i,0,N){
    if(!vis[i]){
        int ki=0,sum=0;
        int temp=A[i],j=i,ti=maxm;
        while(1){
            vis[j]=1;
            ki++;
            ti=min(ti,temp);
            sum+=temp;
            j=hash[temp];
            temp=A[j];
            if(temp==A[i]) break;
        }
        cost+=sum+min((ki-2)*ti,ti+(ki+1)*m);
    }
    }
    printf("%d\n",cost);
    return 0;
}


你可能感兴趣的:(poj 3270 Cow Sorting(置换群))