您的位置:首页 > 其它

hdu 2819 Swap

2017-11-23 12:33 337 查看
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。

先判断最大匹配是不是有n个,在交换匹配后的行和列再记录。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#define maxn 110
using namespace std;
typedef struct
{
int a,b;
} node;
node t[maxn*maxn];
int g[maxn][maxn];
bool used[maxn];
int linker[maxn];
int n;
bool dfs(int u)
{
for(int i=1; i<=n; i++)
{
if(g[u][i]&&!used[i])
{
used[i]=true;
if(linker[i]==-1||dfs(linker[i]))
{
linker[i]=u;
return true;
}
}
}
return false;
}
int hungary()
{
int res=0;
memset(linker,-1,sizeof(linker));
for(int i=1; i<=n; i++)
{
memset(used,false,sizeof(used));
if(dfs(i))res++;
}
return res;
}
int main()
{
while(~scanf("%d",&n))
{
memset(g,0,sizeof(g));
memset(t,0,sizeof(t));
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
scanf("%d",&g[i][j]);
}
if(hungary()<n)
{
cout<<-1<<endl;
continue;
}
int l=0;
for(int i=1; i<=n; i++)
{
if(linker[i]!=i)
{
int j;
for(j=linker[i]; linker[j]!=i; j=linker[j]);
t[l].a=i;
t[l].b=j;
l++;
linker[j]=linker[i];
linker[i]=i;
}
}
cout<<l<<endl;
for(int i=0;i<l;i++)
printf("C %d %d\n",t[i].a,t[i].b);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: