luogu1129 [ZJOI2007]矩阵游戏

其实,只用考虑某一行能否放到某一行就行了

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int T, n, a[205][205], hea[405], cnt, ans, lnk[405];
bool vis[405];
struct Edge{
	int too, nxt;
}edge[80005];
void init(){
	memset(hea, 0, sizeof(hea));
	memset(lnk, 0, sizeof(lnk));
	cnt = 0;
	ans = 0;
}
void add_edge(int fro, int too){
	edge[++cnt].nxt = hea[fro];
	edge[cnt].too = too;
	hea[fro] = cnt;
}
bool dfs(int x){
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(!vis[t]){
			vis[t] = true;
			if(!lnk[t] || dfs(lnk[t])){
				lnk[t] = x;
				return true;
			}
		}
	}
	return false;
}
int main(){
	cin>>T;
	while(T--){
		init();
		cin>>n;
		for(int i=1; i<=n; i++)
			for(int j=1; j<=n; j++)
				scanf("%d", &a[i][j]);
		for(int i=1; i<=n; i++)
			for(int j=1; j<=n; j++)
				if(a[j][i])
					add_edge(j, i+n);
		for(int i=1; i<=n; i++){
			memset(vis, 0, sizeof(vis));
			if(dfs(i))	ans++;
		}
		printf(ans==n?"Yes\n":"No\n");
	}
	return 0;
}
posted @ 2018-01-16 08:29  poorpool  阅读(122)  评论(0编辑  收藏  举报