/* 比较简单的置换群题 首先排成升序 每个元素都有想去的位置 先找轮换 比如1->2 2->3 3->1 那么(1.2.3)就是一个轮换 可以看出他们之间互不影响 然后开始处理每个轮换 可以用数学归纳法证明处理每个小的需要最少换n-1次 为了让代价最小我们那c最小的元素当做中间值 这里有反例 就是如果有一个c很小的数 我们先把这个轮换里的min和这个交换 然后拿这个完成n-1次 最后再换回来 这样可能更优 所以min一下就好了 (讲的太不详细了 具体的可以仔细的上网学习一下) */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1010 #define inf 0x3f3f3f3f using namespace std; int n,f[maxn],ans,cas,sum,mii,Mii,cnt; struct node{ int c,to; bool operator < ( const node & x ) const { return c<x.c; } }p[maxn]; void Clear(){ memset(f,0,sizeof(f)); Mii=inf;ans=0; } int main() { while(scanf("%d",&n)!=EOF){ Clear(); for(int i=1;i<=n;i++){ scanf("%d",&p[i].c); Mii=min(Mii,p[i].c); p[i].to=i; } sort(p+1,p+1+n); for(int i=1;i<=n;i++) if(!f[i]){ sum=0;mii=inf;cnt=0; int r=i; while(!f[r]){ mii=min(mii,p[r].c); sum+=p[r].c;cnt++; f[r]=1;r=p[r].to; } ans+=sum+min((cnt-2)*mii,(cnt+1)*Mii+mii); } if(ans==0)break; printf("Case %d: %d ",++cas,ans); } return 0; }