二分图匹配
可以证明,如果存在n个黑格,且他们互不同行互不同列,就一定有解。相反如果有解,就一定有这样的n个黑格。
于是找完美匹配
#include<cstdio>
#include<cstring>
#define N 205
using namespace std;
struct edge{int next,to;}e[N*N];int ecnt=1;
int last[N], mat[N], n;
bool vis[N];
void add(int a, int b)
{
e[++ecnt]=(edge){last[a],b};
last[a]=ecnt;
}
bool find(int x)
{
for(int i = last[x]; i; i=e[i].next)
{
int y=e[i].to;
if(vis[y])continue;
vis[y]=1;
if(!mat[y] || find(mat[y]))
{
mat[y]=x;
return true;
}
}
return false;
}
int Hungary()
{
int ans=0;
for(int i = 1; i <= n; i++)
{
memset(vis,0,sizeof(vis));
if(find(i))
ans++;
}
return ans;
}
void clear()
{
ecnt=0;
memset(last,0,sizeof(last));
memset(mat,0,sizeof(mat));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
clear();
scanf("%d",&n);
for(int i = 1, x; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
scanf("%d",&x);
if(x)
add(i,j);
}
}
if(Hungary()==n)printf("Yes\n");
else printf("No\n");
}
return 0;
}