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.
Sample Input 2 0 1 1 0 2 1 0 1 0
Sample Output 1 R 1 2 -1 |
题目大意:通过交换行或者交换列,实现对角线全为1;(输入的图只能是0或1)
思路:想象一下,如果第 i 行第 j 个为1,那么就将line[i][j]标为1,然后用匈牙利算法(匈牙利算法自带记录路径)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=115;
int m,n;
int mark[N],line[N][N],r[N];
int mp[N][N];
int found(int a)
{
int i;
for(i=1; i<=n; i++)
{
if(line[a][i]&&!mark[i])
{
mark[i]=1;
if(!r[i]|found(r[i]))
{
r[i]=a;
return 1;
}
}
}
return 0;
}
int main()
{
while(~scanf("%d",&n))
{
int v,i,j,ans=0,s=0;
memset(line,0,sizeof(line));
memset(mp,0,sizeof(mp));
memset(r,0,sizeof(r));
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
{
scanf("%d",&v);
if(v)
line[i][j]=1;
}
for(i=1; i<=n; i++)
{
memset(mark,0,sizeof(mark));
if(found(i))
ans++;
}
if(ans!=n)//如果最大匹配不等于1,那么肯定是错的,输出-1
printf("-1\n");//因为这是二分图最大匹配的结果,要让对角线全为1
else
{
int r1[N],r2[N];
for(i=1; i<=n; i++)
r1[r[i]]=i;
memcpy(r2,r1,sizeof(r2));
for(i=1; i<=n; i++)
{
if(r1[i]!=i)
for(j=i+1; j<=n; j++)
if(r1[j]==i)
{
swap(r1[i],r1[j]);
s++;
}
}
printf("%d\n",s);
for(i=1; i<=n; i++)
{
if(r2[i]!=i)
for(j=i+1; j<=n; j++)
if(r2[j]==i)
{
printf("R %d %d\n",i,j);
swap(r2[i],r2[j]);
}
}
}
}
return 0;
}