HNU 10111 0-1矩阵
http://acm.hnu.cn/online/?action=problem&type=show&id=10111
题意:中文
题解:在龙哥的帮助下正了二分图匹配的三观……以前的理解繁琐,或者有点儿错吧……二分图匹配从左往右匹配,找增广路。顶点数和match()不需要那么麻烦。
1 // 2 // main.cpp 3 // POJ 3041 4 // 5 // Created by zhang on 14-4-16. 6 // Copyright (c) 2014年 apple. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <cstring> 11 #include <cstdio> 12 #include <cstdlib> 13 #include <cmath> 14 #include <string> 15 #include <vector> 16 #include <list> 17 #include <map> 18 #include <queue> 19 #include <stack> 20 #include <bitset> 21 #include <algorithm> 22 #include <numeric> 23 #include <functional> 24 #include <set> 25 #include <fstream> 26 27 using namespace std; 28 29 const int maxn=10010; 30 int g1[maxn]; 31 int g2[maxn]; 32 int V=0; 33 vector<int> G[maxn*2 ]; 34 int match[maxn]; 35 bool used[maxn]; 36 int g[maxn][maxn]; 37 38 void add_edge(int u,int v){ 39 G[u].push_back(v); 40 G[v].push_back(u); 41 } 42 43 bool dfs(int v) 44 { 45 used[v]=true; 46 for (int i=0; i<G[v].size(); i++) { 47 int u=G[v][i]; 48 int w=match[u]; 49 if(used[w]) continue; 50 if (w<0||dfs(w)) { 51 // match[v]=u; 52 match[u]=v; 53 return true; 54 } 55 } 56 return false; 57 } 58 59 int b_match() 60 { 61 int res=0; 62 memset(match, -1, sizeof(match)); 63 for (int v=0; v<V; v++) { 64 if (match[v]<0) { 65 memset(used, 0, sizeof(used)); 66 if (dfs(v)) { 67 res++; 68 } 69 } 70 } 71 return res; 72 } 73 int main() 74 { 75 //freopen("/Users/apple/Desktop/HNU 10111/HNU 10111/in", "r", stdin); 76 //freopen("/Users/apple/Desktop/HNU 10111/HNU 10111/out", "w", stdout); 77 int N,M; 78 char s[110][110]; 79 while((scanf("%d",&N))!=EOF&&N!=0){ 80 scanf("%d",&M); 81 V=N; 82 //cout<<V<<endl; 83 int K=0; 84 int p=0; 85 int q=0; 86 getchar(); 87 for (int i=0; i<N; i++) { 88 for (int j=0; j<M; j++) { 89 s[i][j]=getchar(); 90 // cout<<s[i][j]; 91 if (s[i][j]=='1') { 92 K++; 93 g1[p]=i; 94 g2[q]=j; 95 //cout<<"g1 g2 "<<i <<" "<<j<<" "<<g1[p]<<" "<<g2[q]<<endl; 96 p++; 97 q++; 98 } 99 } 100 getchar(); 101 // puts(""); 102 } 103 //cout<<"K "<<K<<endl; 104 for (int i=0; i<K; i++) { 105 //cout<<g1[i]<<g2[i]<<endl; 106 add_edge(g1[i],N +g2[i]); 107 } 108 printf("%d\n",b_match()); 109 for (int i=0; i<K*2; i++) { 110 G[i].clear(); 111 } 112 } 113 114 return 0; 115 }