您的位置:首页 > 其它

bzoj1059: [ZJOI2007]矩阵游戏

2017-12-15 19:50 337 查看
题面在这里

做法:

如果a[i][j]=1就连一条i−j的边,然后跑二分图最大匹配,如果匹配数为n就可以。

至于为什么的话,可以知道同行同列的点不管怎么交换都还是同行同列,所以只需找到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

, match
, vis
;

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: