传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2819
/*
题意:给出一个01矩阵, 通过交换行或列,来使对角线为1,打印其路径 ,若不能输出-1
思路: 每行获得 一个匹配,即需要交换的 行号来满足要求,因此需要的匹配数目为 n
打印路径 ,根据left数组可以得到一个匹配数组row[n](row[i]==j表初始的第i行应该放到新的第j行去)
那么在row[i+1,n]范围内找到row[j]==i的这个j,然后swap(r[i],r[j])即可
*/
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAXN 111
int n, x;
int map[MAXN][MAXN];
bool mark[MAXN];
int row[MAXN];
int ly[MAXN];
bool dfs(int u)
{
for(int i = 1; i <= n; i++)
{
if(map[u][i] && !mark[i])
{
mark[i] = true;
if(ly[i] == -1 || dfs(ly[i]))
{
ly[i] = u;
return true;
}
}
}
return false;
}
bool MaxMatch()
{
memset(ly, -1, sizeof(ly));
for(int i = 1; i <= n; i++)
{
memset(mark, false, sizeof(mark));
if(!dfs(i))
return false;
}
return true;
}
int main()
{
while(~scanf("%d", &n))
{
memset(map, 0, sizeof(map));
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
scanf("%d", &x);
map[j][i] = x;
}
}
if(!MaxMatch()) //为每行求一个匹配,即改行需要交换的那行
{
puts("-1");
continue;
}
for(int i = 1; i <= n; i++)
{
for(int j = i; j <= n; j++)
{
if(ly[j] == i) // 找到第 i 行需要交换的第 j 行,用row记录下 行号并交换之
{
row[i] = j;
swap(ly[j], ly[i]);
break;
}
}
}
printf("%d\n", n);
for(int i =1 ; i <= n; i++)
printf("R %d %d\n",i,row[i]);
}
return 0;
}