一、内容
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
二、思路
三、代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 105;
struct Node{ int c1, c2;} ans[N * 10];
int n, g[N][N], mat[N]; //代表某列匹配的是哪行
bool vis[N];
bool dfs(int u) {
for (int v = 1; v <= n; v++) {
if (vis[v] || !g[u][v]) continue; vis[v] = true;
if (!mat[v] || dfs(mat[v])) {
mat[v] = u; return true;
}
}
return false;
}
int main() {
while (~scanf("%d", &n)) {
memset(g, 0, sizeof(g));
memset(mat, 0, sizeof(mat));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) scanf("%d", &g[i][j]);
}
int cnt = 0, m = 0;
for (int i = 1; i <= n; i++) {
memset(vis, false, sizeof(vis));
if (dfs(i)) cnt++;
}
if (cnt != n) {printf("-1\n"); continue;}
//交换2列 知道(c, c)的位置为1
for (int c = 1; c <= n; c++) {
while (c != mat[c]) {
ans[++m].c1 = c;
ans[m].c2 = mat[c]; //将(mat[c], c)的1 交换到(mat[c], mat[c])
//那么行和列 匹配 也要交换
swap(mat[c], mat[mat[c]]);
}
}
printf("%d\n", m);
for (int i = 1; i <= m; i++) printf("C %d %d\n", ans[i].c1, ans[i].c2);
}
return 0;
}