Swap
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
二分最大匹配,难在如何建图。这道题要交换任意两行两列,是的对角线都是1,emmmm不知道是什么知识,如果只交换任意两行不能实现的话,那么只交换任意两列或者行列都交换也是不能实现的,好像是矩阵的秩,线性代数里面的东西,还没学就只好先记着了。如果矩阵中一点是1,那就建图e[i][j]=1,代表着我们一会要将j列拉到与i相对应的列,使得e[i][i]=1。同时,如果这个图的最大匹配不是n的话,那是不能满足条件的,所以输出-1。详细看代码理解吧。
#include<cstdio>
#include<cstring>
using namespace std;
#define N 105
bool G[N][N],vis[N];
int Mx[N],My[N],Nx,Ny;
bool dfs(int u)
{
for(int i=1; i<=Ny; ++i)
{
if(G[u][i]&&!vis[i])
{
vis[i]=true;
if(My[i]==-1||dfs(My[i]))
{
My[i]=u;
return true;
}
}
}
return false;
}
int MaxMatch()
{
int ans=0;
memset(Mx,-1,sizeof(Mx));
memset(My,-1,sizeof(My));
for(int i=1; i<=Nx; ++i)
{
if(Mx[i]==-1)
{
memset(vis,false,sizeof(vis));
if(dfs(i)) ++ans;
}
}
return ans;
}
int main()
{
int n,val,sum,ans[N][2];
while(scanf("%d",&n)!=EOF)
{
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=n; ++j)
{
scanf("%d",&val);
G[i][j]=(val==0?false:true);
}
}
Nx=Ny=n;
if(MaxMatch()==n)
{
memset(vis,false,sizeof(vis));
sum=0;
for(int i=1; i<=n; ++i)//*枚举每一列
{
while(!(My[i]==i/*My[i]代表的是行,行数不等于列数*/||vis[My[i]]||vis[i]))
{
++sum;
ans[sum][0]=i;
ans[sum][1]=My[i];
vis[My[i]]=true;
My[i]=My[My[i]];//更换之后的My[i]
}
}
printf("%d\n",sum);
for(int i=1; i<=sum; ++i) printf("C %d %d\n",ans[i][0],ans[i][1]);
}
else printf("-1\n");
}
return 0;
}