Swap HDU - 2819
题意
给一个n*n的矩阵,其值为0或1,通过交换两行或两列将矩阵对角线都为1;
思路
如果一行中或一列中没有1,那么无论怎样交换都无法获得。
只交换行或只交换列一定可以交换出来
用二分图思想,将行数设为二分图的左边,将每行中‘1’的位置列数设为二分图的右面
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <string.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int n;
int a[110][110];
int match[110];
int vis[110];
int dfs(int u)
{
for(int v = 1; v <= n; v ++)
{
if(a[u][v] && !vis[v])
{
vis[v] = 1;
if(match[v] == -1 || dfs(match[v]))
{
match[v] = u;
return 1;
}
}
}
return 0;
}
int f()
{
int ans = 0;
memset(match, - 1, sizeof match);
for(int i = 1; i <= n; i ++)
{
memset(vis, 0, sizeof vis);
ans += dfs(i);
}
return ans;
}
int main()
{
while(~scanf("%d", &n))
{
memset(a, 0, sizeof(a));
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
scanf("%d", &a[i][j]);
if(f() != n)
printf("-1\n");
else
{
int num = 0;
int l[110], r[110];
for(int i = 1; i <= n; i ++)
{
if(i != match[i])
{
for(int j = 1; j <= n; j ++)
{
if(i == match[j])
{
l[num] = i;
r[num] = j;
num ++;
swap(match[i], match[j]);
break;
}
}
}
}
printf("%d\n", num);
for(int i = 0; i < num; i ++)
{
printf("C %d %d\n", l[i], r[i]);
}
}
}
}