1. 程式人生 > >【二分圖】【建圖】bzoj1059 矩陣遊戲

【二分圖】【建圖】bzoj1059 矩陣遊戲

 行列作為點  行為左部 列為右部 黑色格點表示從左部向右部連邊  

使左上角到右下角的連線上的格子均為黑色 一個行只能和一個列連邊  相當於匹配

顯然每種完美匹配對應了一個方案

並不需要考慮如何調換和調換行列後方陣是什麼樣的   從而降低時間複雜度

#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;
 }