Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Re:这题详细用什么方法做?In Reply To:Re:这题详细用什么方法做? Posted by:ccnujing at 2008-08-01 17:15:27 > 置换环... /* * poj3270.cpp * * Created on: 2011-7-20 * Author: will * 群论--置换环--黑书P248 */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using std::cout; using std::endl; int N,mi,ma,S;//S是循环个数 long long ans; int a[10007],b[10007],K[10007],T[10007],ord[100007];//K是循环长度,T是每个循环最小数 int vis[10007];//vis[i]表示i在第几个循环当中 inline int min(int a,int b) { return a<b?a:b; } inline int max(int a,int b) { return a>b?a:b; } int main() { int temp; memset(T,0x3f3f3f,sizeof(T)); mi=999999999; scanf("%d",&N); for(int i=1;i<=N;i++) { scanf("%d",&temp); ord[temp]=i; ans+=temp; mi=min(temp,mi); ma=max(temp,ma); } int now=0; for(int i=0;i<=ma;i++) if(ord[i]) { a[++now]=ord[i]; b[now]=i; } for(int i=1;i<=N;i++) { if(!vis[i]) { S++; K[S]++; T[S]=min(T[S],b[i]); vis[i]=true; now=a[i]; while(!vis[now]) { //printf("now=%d\n",now); K[S]++; T[S]=min(T[S],b[now]); vis[now]=true; now=a[now]; } } } //printf("S=%d\n",S); for(int i=1;i<=S;i++) { ans+=min((K[i]-2)*T[i],T[i]+(K[i]+1)*mi); } cout<<ans<<endl; return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator