码迷,mamicode.com
首页 > 其他好文 > 详细

题解 P1129 【[ZJOI2007]矩阵游戏】

时间:2020-11-13 13:05:27      阅读:5      评论:0      收藏:0      [点我收藏+]

标签:cstring   pac   cst   zjoi   scan   目标   ems   main   std   

交换任意两行或是两列,然后我们最终的目标是要达到该方阵的主对角线上的格子均为黑色(即左上角至右下角)的格子均为黑色。

那么我们每次的操作肯定是将每一行某一个位置上的 1 移到上述的这条对角线,最后判断能否成立,在这样的思路的引导下,我们很容易想到二分图匹配,也就是若 \(a(i)(j)=1\) ,那么我们就要将 \(j\)\(i\) 相连,相当于一个匹配。

判断每一行能否合法匹配即可。

代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define F1(i,l,r) for(int i=l;i<=r;++i)
#define F2(i,r,l) for(int i=r;i>=l;--i)
#define sf(i) scanf("%d",&i)
#define pf(i) printf("%d\n",i)
#define N 207
using namespace std;

int n;
int e[2*N][N],d[N];
bool vis[N];

bool find(int u){
	if(vis[u]) return 0;
	vis[u]=1;
	F1(v,1,n)
		if(e[u][v])
			if(!d[v]||find(d[v])){
				d[v]=u;
				return 1;
			}
	return 0;
}

bool work(){
	F1(i,1,n){
		memset(vis,0,sizeof(vis));
		if(find(i)) continue;
		return 0;
	}
	return 1;
}

int main(){
	int T;
	cin>>T;
	while(T--){
		memset(e,0,sizeof(e));
		memset(d,0,sizeof(d));
		sf(n); 
		F1(i,1,n)
			F1(j,1,n){
				int a;sf(a);
				if(a) e[j][i]=1;
			}
		if(work()) printf("Yes\n");
		else printf("No\n");
	}
}

多组数据记得清零,我第一次交就因为d数组没有清零爆零了

题解 P1129 【[ZJOI2007]矩阵游戏】

标签:cstring   pac   cst   zjoi   scan   目标   ems   main   std   

原文地址:https://www.cnblogs.com/Niuwadiandian/p/13944730.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!