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*n的01矩阵,问能否通过交换行或列,使得主对角线上的数全为1?
思路
先求出最大匹配数,如果等于n,就可以实现。
只换行或者只换列,就能使对角线上的数全为1。
枚举每一行,对于第i行,找到与第i列匹配的那一行j,然后交换第i行和第j行。这样就满足题目要求
代码
#include<bits/stdc++.h>
using namespace std;
int a[110][110];
int book[110];
int x[110],y[110];
int n;
int dfs(int u)
{
for(int i=1; i<=n; i++)
{
if(book[i]==0&&a[u][i]==1)
{
book[i]=1;
if(y[i]==0||dfs(y[i]))
{
y[i]=u;
x[u]=i;
return 1;
}
}
}
return 0;
}
int hungary()
{
int ans=0;
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
for(int i=1; i<=n; i++)
{
memset(book,0,sizeof(book));
if(dfs(i))
ans++;
}
return ans;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&a[i][j]);
int cnt=hungary();
//printf("%d\n",cnt);
if(cnt<n)
printf("-1\n");
else
{
int op[110][2];
int sum=0;
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(x[j]==i)
{
swap(x[j],x[i]);
op[++sum][0]=i;
op[sum][1]=j;
break;
}
}
}
printf("%d\n",sum);
for(int i=1;i<=sum;i++)
printf("R %d %d\n",op[i][0],op[i][1]);
}
}
return 0;
}