HDU2819 Swap —— 二分图最大匹配
题目链接:https://vjudge.net/problem/HDU-2819
Swap
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4003 Accepted Submission(s): 1478
Special Judge
Problem Description
Given an N*N matrix with each entry equal to 0 or 1. You can swap any two rows or any two columns. Can you find a way to make all the diagonal entries equal to 1?
Input
There are several test cases in the input. The first line of each test case is an integer N (1 <= N <= 100). Then N lines follow, each contains N numbers (0 or 1), separating by space, indicating the N*N matrix.
Output
For each test case, the first line contain the number of swaps M. Then M lines follow, whose format is “R a b” or “C a b”, indicating swapping the row a and row b, or swapping the column a and column b. (1 <= a, b <= N). Any correct answer will be accepted, but M should be more than 1000.
If it is impossible to make all the diagonal entries equal to 1, output only one one containing “-1”.
If it is impossible to make all the diagonal entries equal to 1, output only one one containing “-1”.
Sample Input
2
0 1
1 0
2
1 0
1 0
Sample Output
1
R 1 2
-1
Source
Recommend
gaojie
题解:
题意:给出一个大小为n*n的01矩阵,问能否通过交换行或列,使得主对角线上的数全为1?
1.用匈牙利算法求出最大匹配数cnt,如果cnt等于n,则可以实现。
2.可知,我们可以通过只交换行或者只交换列,就能使得主对角线上的数全为1。
3.枚举每一行i,对于第i行,找到与第i列匹配的那一行k,然后交换第i行和第k行。这样就满足了第i行有1在对角线上。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <sstream> 11 #include <algorithm> 12 using namespace std; 13 const int INF = 2e9; 14 const int MOD = 1e9+7; 15 const int MAXN = 100+10; 16 17 int n; 18 int M[MAXN][MAXN], id[MAXN][MAXN], xlink[MAXN], ylink[MAXN]; 19 bool vis[MAXN]; 20 21 bool dfs(int u) 22 { 23 for(int i = 1; i<=n; i++) 24 if(M[u][i] && !vis[i]) 25 { 26 vis[i] = true; 27 if(ylink[i]==-1 || dfs(ylink[i])) 28 { 29 ylink[i] = u; 30 xlink[u] = i; 31 return true; 32 } 33 } 34 return false; 35 } 36 37 int hungary() 38 { 39 int ret = 0; 40 memset(xlink, -1, sizeof(xlink)); 41 memset(ylink, -1, sizeof(ylink)); 42 for(int i = 1; i<=n; i++) 43 { 44 memset(vis, 0, sizeof(vis)); 45 if(dfs(i)) ret++; 46 } 47 return ret; 48 } 49 50 int main() 51 { 52 while(scanf("%d", &n)!=EOF) 53 { 54 for(int i = 1; i<=n; i++) 55 for(int j = 1; j<=n; j++) 56 scanf("%d", &M[i][j]); 57 58 int cnt = hungary(); 59 if(cnt<n) 60 { 61 printf("-1\n"); 62 continue; 63 } 64 65 int ans = 0, op[MAXN][2]; 66 for(int i = 1; i<n; i++) 67 for(int j = i+1; j<=n; j++) 68 { 69 if(xlink[j]==i) 70 { 71 swap(xlink[j], xlink[i]); 72 op[++ans][0] = i; op[ans][1] = j; 73 break; 74 } 75 } 76 77 printf("%d\n", ans); 78 for(int i = 1; i<=ans; i++) 79 printf("R %d %d\n", op[i][0], op[i][1]); 80 } 81 }