题目:HDU - 2819
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
求出最大匹配。若最大匹配小于n,就不能。
之后输出交换的路径,逐行遍历,如果第i行匹配的值不是第i列(主对角线的x和y当然相等了),那就再次遍历寻找哪行匹配的是第i列。假如,我们找到第k行匹配的是第i列,那我们就将i和k进行交换,注意,交换之后我们要将他们的匹配值也要交换,因为操作是再上一次操作之后进行的
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 110;
int un,vn;
int g[maxn][maxn];
int linker[maxn];
bool used[maxn];
int n;
bool dfs(int u)
{
for(int v = 1;v <= n;v ++)
{
if(g[u][v] && !used[v])
{
used[v] = true;
if(linker[v] == -1 || dfs(linker[v]))
{
linker[v] = u;
return true;
}
}
}
return false;
}
int hungary()
{
int res = 0;
memset(linker,-1,sizeof(linker));
for(int u = 1;u <= n;u ++)
{
memset(used,false,sizeof(used));
if(dfs(u)) res ++;
}
return res;
}
int main()
{
int i,j;
int a[10000];
int b[10000];
while(cin >> n)
{
un = vn = n;
memset(g,0,sizeof(g));
for(i = 1;i <= n;i ++)
{
for(j = 1;j <= n;j ++)
{
cin >> g[i][j];
}
}
int ans = hungary();
int res = 0;
if(ans < n)
{
cout << "-1" << endl;
continue;
}
for(i = 1;i <= n;i ++)
{
for(j = i;j <= n;j ++)
{
if(linker[j] == i) break;
}
if(j != i)
{
a[res] = i;
b[res ++] = j;
int t = linker[i];
linker[i] = linker[j];
linker[j] = t;
}
}
cout << res << endl;
for(i = 0;i < res;i ++)
printf("C %d %d\n",a[i],b[i]);
}
return 0;
}