做法:
如果
a[i][j]=1
就连一条
i−j
的边,然后跑二分图最大匹配,如果匹配数为
n
就可以。
至于为什么的话,可以知道同行同列的点不管怎么交换都还是同行同列,所以只需找到
ps.话说为什么很多大佬都喜欢写dinic啊orzorz。。。本蒟蒻默默地写了一发匈牙利= =
/*************************************************************
Problem: bzoj 1059 [ZJOI2007]矩阵游戏
User: fengyuan
Language: C++
Result: Accepted
Time: 384 ms
Memory: 1456 kb
Submit_Time: 2017-12-15 19:32:34
*************************************************************/
#include<bits/stdc++.h>
#define rep(i, x, y) for (int i = (x); i <= (y); i ++)
#define down(i, x, y) for (int i = (x); i >= (y); i --)
#define mid ((l+r)/2)
#define lc (o<<1)
#define rc (o<<1|1)
#define pb push_back
#define mp make_pair
#define PII pair<int, int>
#define F first
#define S second
#define B begin()
#define E end()
using namespace std;
typedef long long LL;
//head
const int N = 205;
int n;
int a[N][N], match[N], vis[N];
inline bool dfs(int u)
{
rep(i, 1, n) if (a[u][i] && !vis[i]){
vis[i] = 1;
if (!match[i] || dfs(match[i])){
match[i] = u;
return 1;
}
}
return 0;
}
int main()
{
int Test; scanf("%d", &Test);
while (Test --){
scanf("%d", &n);
memset(a, 0, sizeof a);
rep(i, 1, n) rep(j, 1, n) scanf("%d", &a[i][j]);
memset(match, 0, sizeof match);
int ret = 0;
rep(i, 1, n){
memset(vis, 0, sizeof vis);
if (dfs(i)) ret ++;
}
if (ret == n) puts("Yes"); else puts("No");
}
return 0;
}