HDU2819
Posted Blogggggg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU2819相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2819
题目大意:
给出一个N*N的0/1矩阵,只能交换整行或者整列,问最少交换多少次可以变成一个主对角线上的数都为1的矩阵。
解题思路:
对行和列进行二分匹配,如果行和列之间不是完全匹配,直接输出 -1;否则就对匈牙利算法匹配后的得到的每一列对应的行进行操作(当然你也可以是对列进行操作,后面的交换也要进行相应的调整),如果行i不对应于列i,而行j对应列i,那么交换第i,j列。好题!
AC代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn=100+5; 6 bool link[maxn][maxn],vis[maxn]; 7 int col[maxn]; //记录匈牙利算法跑完以后各列所匹配的行 8 int N; 9 pair<int,int> ans[maxn]; 10 bool finds(int x){ 11 for(int i=1;i<=N;i++){ 12 if(link[x][i]&&!vis[i]){ 13 vis[i]=true; 14 if(col[i]==0||finds(col[i])){ 15 col[i]=x; 16 return true; 17 } 18 } 19 } 20 return false; 21 } 22 int main(){ 23 int t; 24 while(scanf("%d",&N)==1){ 25 for(int i=1;i<=N;i++){ 26 for(int j=1;j<=N;j++){ 27 scanf("%d",&t); 28 if(t) link[i][j]=true; 29 else link[i][j]=false; 30 } 31 } 32 memset(col,false,sizeof(col)); 33 bool no=false; 34 for(int i=1;i<=N;i++){ 35 memset(vis,false,sizeof(vis)); 36 if(!finds(i)){ 37 no=true; break; 38 } 39 } 40 if(no) printf("-1\n"); 41 else{ 42 int cnt=0; 43 for(int i=1;i<=N;i++){ 44 if(col[i]==i) continue; 45 else{ 46 for(int j=i+1;j<=N;j++){ 47 if(col[j]==i){ 48 ans[cnt]=make_pair(i,j); 49 col[j]=col[i]; 50 cnt++; 51 } 52 } 53 } 54 } 55 printf("%d\n",cnt); 56 for(int i=0;i<cnt;i++){ 57 printf("C %d %d\n",ans[i].first,ans[i].second); 58 } 59 } 60 } 61 return 0; 62 }
以上是关于HDU2819的主要内容,如果未能解决你的问题,请参考以下文章