【BZOJ1059】矩阵游戏(二分图最大匹配)
题意:矩阵游戏在一个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 }
null