【二分圖】【建圖】bzoj1059 矩陣遊戲
阿新 • • 發佈:2018-12-11
行列作為點 行為左部 列為右部 黑色格點表示從左部向右部連邊
使左上角到右下角的連線上的格子均為黑色 一個行只能和一個列連邊 相當於匹配
顯然每種完美匹配對應了一個方案
並不需要考慮如何調換和調換行列後方陣是什麼樣的 從而降低時間複雜度
#include<cstdio> #include<cstring> using namespace std; const int N=200+5; int n,m,match[N]; bool vis[N]; int num,last[N],nxt[N*N],ver[N*N]; inline void add(int x,int y) {nxt[++num]=last[x]; last[x]=num; ver[num]=y;} bool dfs(int x) {for(int i=last[x],y;i;i=nxt[i]) {if(!vis[y=ver[i]]) {vis[y]=1; if(!match[y] || dfs(match[y])) {match[y]=x; return 1;} } } return 0; } int main() { int t,r,cnt; scanf("%d",&t); while(t--) {memset(match,0,sizeof(match)); memset(last,0,sizeof(last)); cnt=num=0; scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) {scanf("%d",&r); if(r) add(i,j); } for(int i=1;i<=n;i++) {memset(vis,0,sizeof(vis)); if(dfs(i)) cnt++; else break; } if(cnt==n) printf("Yes\n"); else printf("No\n"); } return 0; }