1. 程式人生 > >【BZOJ1059】矩陣遊戲(二分圖最大匹配)

【BZOJ1059】矩陣遊戲(二分圖最大匹配)

set 交換 tdi namespace 顏色 pac 連線 include amp

題意:矩陣遊戲在一個N*N黑白方陣進行。每次可以對該矩陣進行兩種操作:

行交換操作:選擇矩陣的任意兩行,交換這兩行(即交換對應格子的顏色)

列交換操作:選擇矩陣的任意行列,交換這兩列(即交換對應格子的顏色)

遊戲的目標,即通過若幹次操作,使得方陣的主對角線(左上角到右下角的連線)上的格子均為黑色。

要求判斷是否有解

n<=200

思路:原先同行或同列的格子後依舊同行或同列

轉化為是否能找到n個行列互不相同的點

行列建邊後跑二分圖最大匹配即可

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<string
> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int
,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define N 110000 21 #define M 410000 22 #define eps 1e-8 23 #define pi acos(-1) 24 #define oo 1e9 25 int head[N],vet[N],nxt[N],match[N],flag[N],tot; 26 27 28 void add(int a,int b) 29 { 30
nxt[++tot]=head[a]; 31 vet[tot]=b; 32 head[a]=tot; 33 } 34 35 int dfs(int u) 36 { 37 flag[u]=1; 38 int e=head[u]; 39 while(e) 40 { 41 int v=vet[e]; 42 if(!match[v]||!flag[match[v]]&&dfs(match[v])) 43 { 44 match[v]=u; 45 return 1; 46 } 47 e=nxt[e]; 48 } 49 return 0; 50 } 51 52 int main() 53 { 54 int cas; 55 scanf("%d",&cas); 56 while(cas--) 57 { 58 int n; 59 scanf("%d",&n); 60 memset(head,0,sizeof(head)); 61 memset(match,0,sizeof(match)); 62 tot=0; 63 for(int i=1;i<=n;i++) 64 for(int j=1;j<=n;j++) 65 { 66 int x; 67 scanf("%d",&x); 68 if(x) add(i,j); 69 } 70 int ans=0; 71 for(int i=1;i<=n;i++) 72 { 73 memset(flag,0,sizeof(flag)); 74 if(dfs(i)) ans++; 75 } 76 //printf("%d\n",ans); 77 if(ans==n) printf("Yes\n"); 78 else printf("No\n"); 79 } 80 return 0; 81 }

【BZOJ1059】矩陣遊戲(二分圖最大匹配)