POJ-3270 Cow Sorting 置换群

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

  把数列循环分解,注意到长度为k的循环最少用k-1次置换,那么次循环的最优值就是用循环中的最小值去与每个置换,还要考虑此循环中的最优值可以由其它循环影响,影响的那个循环肯定还有数列中的最小值。

 1 //STATUS:C++_AC_16MS_396KB
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<iostream>
 7 #include<string>
 8 #include<algorithm>
 9 #include<vector>
10 #include<queue>
11 #include<stack>
12 #include<map>
13 using namespace std;
14 #define LL long long
15 #define pii pair<int,int>
16 #define Max(a,b) ((a)>(b)?(a):(b))
17 #define Min(a,b) ((a)<(b)?(a):(b))
18 #define mem(a,b) memset(a,b,sizeof(a))
19 #define lson l,mid,rt<<1
20 #define rson mid+1,r,rt<<1|1
21 const int N=10010,INF=0x3f3f3f3f,MOD=60007,STA=1000010;
22 const LL LNF=0x3f3f3f3f3f3f3f3f;
23 const double DNF=100000000000;
24 
25 int num[N],c[N],ma[N*10],vis[N],minu[N],cnt[N],s[N];
26 int n;
27 
28 int main()
29 {
30  //   freopen("in.txt","r",stdin);
31     int i,j,u,ans,k,t,minc;
32     while(~scanf("%d",&n))
33     {
34         ans=k=0;
35         minc=INF;
36         mem(vis,0);
37         for(i=1;i<=n;i++){
38             scanf("%d",&num[i]);
39             c[i]=num[i];
40         }
41         sort(c+1,c+n+1);
42         for(i=1;i<=n;i++)
43             ma[c[i]]=i;
44 
45         for(i=1;i<=n;i++){
46             if(!vis[i]){
47                 minu[k]=INF;
48                 cnt[k]=s[k]=0;
49                 u=i;
50                 while(!vis[u]){
51                     vis[u]=1;
52                     minu[k]=Min(minu[k],c[u]);
53                     minc=Min(minc,c[u]);
54                     s[k]+=c[u];
55                     cnt[k]++;
56                     u=ma[num[u]];
57                 }
58                 s[k]=s[k]+(cnt[k]-2)*minu[k];
59                 k++;
60             }
61         }
62         for(i=0;i<k;i++){
63             ans+=Min(s[i],s[i]+2*(minu[i]+minc)-(cnt[i]-1)*(minu[i]-minc));
64         }
65 
66         printf("%d\n",ans);
67     }
68     return 0;
69 }

 

posted @ 2013-04-08 00:50  zhsl  阅读(282)  评论(0编辑  收藏  举报