标签: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数组没有清零爆零了
标签:cstring pac cst zjoi scan 目标 ems main std
原文地址:https://www.cnblogs.com/Niuwadiandian/p/13944730.html