bzoj 1059: [ZJOI2007]矩阵游戏【匈牙利算法】

注意到怎么换都行,但是如果把某个黑方块用在对角线上,它原来所在的行列的的黑方块就都不能用
所以要选出n组不重的行列组合,这里用匈牙利算法做二分图匹配即可(用了时间戳优化)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=405;
int T,n,cnt,h[N],lk[N],v[N],ti;
struct qwe
{
	int ne,to;
}e[N*N];
int read()
{
	int r=0,f=1;
	char p=getchar();
	while(p>'9'||p<'0')
	{
		if(p=='-')
			f=-1;
		p=getchar();
	}
	while(p>='0'&&p<='9')
	{
		r=r*10+p-48;
		p=getchar();
	}
	return r*f;
}
void add(int u,int v)
{
	cnt++;
	e[cnt].ne=h[u];
	e[cnt].to=v;
	h[u]=cnt;
}
bool dfs(int u)
{
	for(int i=h[u];i;i=e[i].ne)
		if(v[e[i].to]!=ti)
		{
			v[e[i].to]=ti;
			if(!lk[e[i].to]||dfs(lk[e[i].to]))
			{
				lk[e[i].to]=u;
				return 1;
			}
		}
	return 0;
}
int main()
{
	T=read();
	while(T--)
	{
		cnt=0;ti=0;
		memset(h,0,sizeof(h));
		memset(v,0,sizeof(v));
		memset(lk,0,sizeof(lk));
		n=read();
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				int x=read();
				if(x)
					add(i,j);
			}
		int con=0;
		for(int i=1;i<=n;i++)
		{
			ti++;
			if(dfs(i))
				con++;
		}
		if(con==n)
			puts("Yes");
		else
			puts("No");
	}
	return 0;
}
posted @ 2018-07-26 22:53  lokiii  阅读(141)  评论(0编辑  收藏  举报