原题:http://acm.hdu.edu.cn/showproblem.php?pid=2819
题意:
给定一个n*n的01矩阵;
通过行或列的变换使得主对角线上都为1;
问变换次数,以及具体的变换操作;
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 110;
int n;
int match[maxn];
int a[maxn], b[maxn];
bool used[maxn];
vector<int>G[maxn];
bool find(int x)
{
for(int i = 0;i<G[x].size();i++)
{
int k = G[x][i];
if(!used[k])
{
used[k] = true;
if(match[k] == 0 || find(match[k]))
{
match[k] = x;
return true;
}
}
}
return false;
}
int main()
{
while(scanf("%d", &n)!=EOF)
{
memset(match, 0, sizeof match);
for(int i = 1;i<=n;i++)
{
G[i].clear();
for(int j = 1;j<=n;j++)
{
int x;
scanf("%d", &x);
if(x == 1)
G[i].push_back(j);
}
}
int sum = 0;
for(int i = 1;i<=n;i++)
{
memset(used, false, sizeof used);
if(find(i))
sum++;
}
if(sum<n) printf("-1\n");
else
{
int t = 0;
int i, j;
for(i = 1;i<=n;i++)
{
for(j = i;j<=n;j++)
{
if(match[j] == i) //找到可以和i交换的j列;
break;
}
if(j!=i) //i = j表示该位置本身就是1,不需要交换;
{
a[t] = i;
b[t++] = j;
swap(match[i], match[j]); //交换过后相关的1的位置就要改变;
}
}
printf("%d\n", t);
for(int i = 0;i<t;i++)
printf("C %d %d\n", a[i], b[i]);
}
}
return 0;
}