标签:输入 通过 namespace TE s/4 选择 交换 using opened
3
3 2 1
4
8 1 2 4
5
1 8 9 7 6
6
8 4 5 3 2 7
0
Case 1: 4
Case 2: 17
Case 3: 41
Case 4: 34
首先要明白最小交换次数的算法,大致就是n - n被分解成单循环的个数
具体参照这个博客https://blog.csdn.net/wangxugangzy05/article/details/42454111
然后这题就离散化一下,找出每个单循环,比较计算最小值就行了
#include<bits/stdc++.h> using namespace std; int n,team3[100000]; int team[100000]; int Sum,Min,Num; int check[100000]= {0}; void f(int x) { if(check[x]==1)return; Sum+=team[x]; Min=min(Min,team[x]); Num++; check[x]=1; f(team3[x]); } int main() { int tot=0,ans=0,all_min=INT_MAX; int team2[100000]; while(scanf("%d",&n)==1) { if(n==0)return 0; all_min=INT_MAX; ans=0; for(int i=1; i<=n; i++)scanf("%d",&team[i]),team2[i]=team[i],all_min=min(all_min,team[i]); sort(team2+1,team2+1+n); int size=unique(team2+1,team2+1+n)-team2-1; for(int i=1; i<=n; i++) team3[i]=lower_bound(team2+1,team2+1+size,team[i])-team2; memset(check,0,sizeof(check)); for(int i=1; i<=n; i++) if(check[i]==0) { Sum=0; Min=INT_MAX; Num=0; f(i); ans+=min(Min*(Num-1),all_min*(Num-1)+2*(Min+all_min))+(Sum-Min); } printf("Case %d: %d\n\n",++tot,ans); } return 0; }
标签:输入 通过 namespace TE s/4 选择 交换 using opened
原文地址:https://www.cnblogs.com/tian-luo/p/9222318.html