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”. 
 

 

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 }
View Code

 

posted on 2017-11-11 09:45  h_z_cong  阅读(168)  评论(0编辑  收藏  举报

导航