码迷,mamicode.com
首页 > 其他好文 > 详细

HDU2819

时间:2017-08-25 21:41:42      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:ons   调整   turn   ble   first   bre   while   cond   blog   

题目链接: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

标签:ons   调整   turn   ble   first   bre   while   cond   blog   

原文地址:http://www.cnblogs.com/Blogggggg/p/7429713.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!