Swap
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
题意:给一个n*n只有0和1的矩阵,判断经过一系列行列变换后能否得到一个对角线全为一的矩阵。
思路:要想得到一个对角线全为1的矩阵,就必须每一行或者每一列都至少有一个1,所以就可以通过行和列的最大匹配数来判断能否得到这样的矩阵,如果最大匹配数为n的话就说明能得到对角线全为1的矩阵。
除了判断能否得到这样的矩阵,题目还要求我们求出行列的变换过程,因为在求行列最大匹配的过程中,求出了match[j]=i;
所以我们可以通过这个match数组来实现变换。
我们可以枚举每一行,找到匹配到这行的列的位置,因为要在对角线的位置上,所以就可以判断此时的i是否等于j,如果不等于的话就要进行交换。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define maxn 210
int vis[maxn],mp[maxn][maxn],match[maxn],a[maxn],b[maxn];
int n;
int dfs(int u)
{
int i;
for(i=1; i<=n; i++)
{
if(mp[u][i]&&!vis[i])
{
vis[i]=1;
if(!match[i]||dfs(match[i]))
{
match[i]=u;
return 1;
}
}
}
return 0;
}
int main()
{
while(~scanf("%d",&n))
{
memset(mp,0,sizeof(mp));
memset(match,0,sizeof(match));
int i,j,x;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
scanf("%d",&x);
if(x==1) mp[i][j]=1;
}
}
int sum=0;
for(i=1; i<=n; i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i)) sum++;
}
if(sum<n)
{
printf("-1\n");
continue;
}
int cnt=0;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
if(match[j]==i) break;
if(i!=j)
{
a[cnt]=i;
b[cnt]=j;
cnt++;
int tmp=match[i];
match[i]=match[j];
match[j]=tmp;
}
}
printf("%d\n",cnt);
for(i=0; i<cnt; i++)
printf("C %d %d\n",a[i],b[i]);
}
return 0;
}