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”.
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
题意:给出一个01矩阵,每次交换某两行或者某两列,使得最终矩阵对角线全是1,问是否可行,可行输出交换次数及方法
做法:1A好开心~~~~
这种nxn矩阵神马的很容易想到是让行作为左边,列作为右边,位置是1的连边,如果是最大匹配数是n那么可解。问题是如何交换?根据增广路的思想,我们尽量去满足匹配的要求(说是增广路有点牵强啊==)由于跑匈牙利的时候是linker[y]=x那么当我们发现有一组的linker[i]!=i时就要交换swap(linker[i],linker[linker[i]]);一直递归下去就完事了
#include <iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define M 550
#define MAXN 100
#define inf 0x3f3f3f3f
int uN,vN;//u,v数目
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
bool dfs(int u)//从左边开始找增广路径
{
int v;
for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改
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()
{
// puts("hungary");
int res=0;
int u;
memset(linker,-1,sizeof(linker));
for(u=0;u<uN;u++)
{
memset(used,0,sizeof(used));
if(dfs(u)) res++;
}
return res;
}
int t,m,n,tot;
vector< pair<int,int> >ans;
void dfs2(int x)
{
ans.push_back(make_pair(linker[x]+1,linker[linker[x]]+1));
// printf("R %d %d\n",,);
tot++;
swap(linker[x],linker[linker[x]]);
bool exi=0;
for(int i=0;i<n;i++)
{
if(linker[i]!=i)
{
dfs2(i);
exi=1;
break;
}
}
return;
}
int main()
{
// freopen("cin.txt","r",stdin);
while(~scanf("%d",&n))
{
uN=n;
vN=n;
memset(g,0,sizeof(g));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int x;
scanf("%d",&x);
if(x==1)g[i][j]=1;
}
}
if(hungary()!=n)puts("-1");
else
{
tot=0;
ans.clear();
for(int i=0;i<n;i++)
{
if(linker[i]!=i)
{
dfs2(i);
break;
}
}
printf("%d\n",tot);
for(int i=0;i<ans.size();i++)
printf("R %d %d\n",ans[i].first,ans[i].second);
}
}
return 0;
}