Swap HDU - 2819

//把矩阵按行和列缩点,格子为1的就在所在行列加边
//然后二分图求最大匹配,如果是n,代表可行,小于n就输出-1
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100+10;
int g[N][N];
int match[N];
bool used[N];
int n;
bool find(int u) {
	for(int i=1; i<=n; i++) {
		if(used[i]||!g[u][i]) continue;
		used[i]=true;
		if(match[i]==-1||find(match[i])) {
			match[i]=u;
			return true;
		}
	}
	return false;
}
int solve() {
	int res=0;
	memset(match,-1,sizeof match);
	for(int i=1; i<=n; i++) 
	{
		memset(used,false,sizeof(used));
		if(find(i)) 
			res++;
	}
	return res;
}
int a[N],b[N];
int main() {
	while(~scanf("%d",&n)) 
	{
		for(int i=1; i<=n; i++)
			for(int j=1; j<=n; j++)
				scanf("%d",&g[i][j]);
		int num=solve();
		if(num==n)
		{
			int m=0;
			for(int i=1; i<=n; i++) 
			{
				while(match[i]!=i) 
				{
					a[m]=i;
					b[m]=match[i];
					m++;
					int t=match[i];
					match[i]=match[match[i]];
					match[t]=t;
				}
			}
			printf("%d\n",m);
			for(int i=0; i<m; i++)
				printf("C %d %d\n",a[i],b[i]);
		} else 
			printf("-1\n");
	}
	return 0;
}

posted @ 2020-03-05 21:02  晴屿  阅读(93)  评论(0编辑  收藏  举报