首页 > 代码库 > POJ 3270 Cow Sorting
POJ 3270 Cow Sorting
这道题运用了置换的知识。
题目大意:
用两两交换的方式给一个数列排序,每交换一次的代价是这两个数之和求最小代价。
解题思路:
对于这种情况,我们在数列中找置换环。每个置换环内的数都是可以回归到它应有的位置上并且不影响其他的置换环。
置换环归位的代价有两种,第一种是用环内最小的数与其他数交换,另一种是用整个数列中最小的数与环内最小的数交换,完成环内所有数的归位后在换回去。
下面是代码:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #define clear(A, X, SIZE) memset(A, X, sizeof(A[0]) * (SIZE)) #define clearall(A, X) memset(A, X, sizeof(A)) #define max( x, y ) ( ((x) > (y)) ? (x) : (y) ) #define min( x, y ) ( ((x) < (y)) ? (x) : (y) ) using namespace std; struct node { int num,po1,po2; } x[10005]; bool cmp(const node a,const node b) { return a.num<b.num; } bool cmp1(const node a,const node b) { return a.po1<b.po1; } int num[10005],po[10005]; bool vis[10005]; int main() { int n,minnum,min2,minp,cost1,cost2,ans,tp; while(scanf("%d",&n)!=EOF) { ans=0; minnum=1<<30; for(int i=0; i<n; i++) { scanf("%d",&num[i]); x[i].num=num[i]; x[i].po1=i; minnum=min(minnum,num[i]); } sort(x,x+n,cmp); for(int i=0; i<n; i++) { x[i].po2=i; po[i]=x[i].po1; } sort(x,x+n,cmp1); clearall(vis,false); int cnt=n,p; bool flat; for(int i=0; i<n&&cnt; i++) { if(!vis[i]) { vis[i]=true; p=x[i].po2; min2=x[i].num; minp=i; while(p!=i) { vis[p]=true; if(min2>x[p].num) { min2=x[p].num; minp=p; } p=x[p].po2; } cost1=0; cost2=0; p=minp; while(p!=x[minp].po2) { cost1+=x[po[p]].num+min2; cost2+=x[po[p]].num+minnum; p=po[p]; } ans+=min(cost1,cost2+2*(min2+minnum)); } } printf("%d\n",ans); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。