标签:多重 getchar none ret contact eof sample hose using
题目链接:https://vjudge.net/problem/POJ-2289
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 8147 | Accepted: 2736 |
Description
Input
Output
Sample Input
3 2 John 0 1 Rose 1 Mary 1 5 4 ACM 1 2 3 ICPC 0 1 Asian 0 2 3 Regional 1 2 ShangHai 0 2 0 0
Sample Output
2 2
Source
题解:
多重匹配:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <sstream> 11 #include <algorithm> 12 using namespace std; 13 const int INF = 2e9; 14 const int MOD = 1e9+7; 15 const int MAXM = 5e2+10; 16 const int MAXN = 1e3+10; 17 18 int uN, vN; 19 int num[MAXM], linker[MAXM][MAXN]; 20 bool g[MAXN][MAXM], used[MAXM]; 21 22 bool dfs(int u) 23 { 24 for(int v = 0; v<vN; v++) 25 if(g[u][v] && !used[v]) 26 { 27 used[v] = true; 28 if(linker[v][0]<num[v]) 29 { 30 linker[v][++linker[v][0]] = u; 31 return true; 32 } 33 for(int i = 1; i<=num[v]; i++) 34 if(dfs(linker[v][i])) 35 { 36 linker[v][i] = u; 37 return true; 38 } 39 } 40 return false; 41 } 42 43 bool hungary(int mid) 44 { 45 for(int i = 0; i<vN; i++) 46 { 47 num[i] = mid; 48 linker[i][0] = 0; 49 } 50 for(int u = 0; u<uN; u++) 51 { 52 memset(used, false, sizeof(used)); 53 if(!dfs(u)) return false; 54 } 55 return true; 56 } 57 58 char tmp[100000]; 59 int main() 60 { 61 while(scanf("%d%d", &uN, &vN) && (uN||vN)) 62 { 63 memset(g, false, sizeof(g)); 64 getchar(); 65 for(int i = 0; i<uN; i++) 66 { 67 gets(tmp); 68 int j = 0, len = strlen(tmp); 69 while(tmp[j]!=‘ ‘ && j<len) j++; 70 j++; 71 for(int v = 0; j<=len; j++) 72 { 73 if(tmp[j]==‘ ‘||j==len) 74 { 75 g[i][v] = true; 76 v = 0; 77 } 78 else v = v*10+(tmp[j]-‘0‘); 79 } 80 } 81 82 int l = 1, r = uN; 83 while(l<=r) 84 { 85 int mid = (l+r)>>1; 86 if(hungary(mid)) 87 r = mid - 1; 88 else 89 l = mid + 1; 90 } 91 printf("%d\n", l); 92 } 93 }
最大流:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <sstream> 11 #include <algorithm> 12 using namespace std; 13 const int INF = 2e9; 14 const int MOD = 1e9+7; 15 const int MAXM = 5e2+10; 16 const int MAXN = 2e3+10; 17 18 struct Edge 19 { 20 int to, next, cap, flow; 21 }edge[MAXN*MAXN]; 22 int tot, head[MAXN]; 23 24 int uN, vN, maze[MAXN][MAXN]; 25 int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN]; 26 27 void add(int u, int v, int w) 28 { 29 edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0; 30 edge[tot].next = head[u]; head[u] = tot++; 31 edge[tot].to = u; edge[tot].cap = 0; edge[tot].flow = 0; 32 edge[tot].next = head[v]; head[v] = tot++; 33 } 34 35 int sap(int start, int end, int nodenum) 36 { 37 memset(gap,0,sizeof(gap)); 38 memset(dep,0,sizeof(dep)); 39 memcpy(cur,head,sizeof(head)); 40 41 int u = start; 42 pre[u] = -1; 43 gap[0] = nodenum; 44 int maxflow = 0; 45 while(dep[start]<nodenum) 46 { 47 bool flag = false; 48 for(int i = cur[u]; i!=-1; i=edge[i].next) 49 { 50 int v = edge[i].to; 51 if(edge[i].cap-edge[i].flow && dep[v]+1==dep[u]) 52 { 53 flag = true; 54 cur[u] = pre[v] = i; 55 u = v; 56 break; 57 } 58 } 59 60 if(flag) 61 { 62 if(u==end) 63 { 64 int minn = INF; 65 for(int i = pre[u]; i!=-1; i=pre[edge[i^1].to]) 66 if(minn>edge[i].cap-edge[i].flow) 67 minn = edge[i].cap-edge[i].flow; 68 for(int i = pre[u]; i!=-1; i=pre[edge[i^1].to]) 69 { 70 edge[i].flow += minn; 71 edge[i^1].flow -= minn; 72 } 73 u = start; 74 maxflow += minn; 75 } 76 } 77 78 else 79 { 80 int minn = nodenum; 81 for(int i = head[u]; i!=-1; i=edge[i].next) 82 if(edge[i].cap-edge[i].flow && dep[edge[i].to]<minn) 83 { 84 minn = dep[edge[i].to]; 85 cur[u] = i; 86 } 87 gap[dep[u]]--; 88 if(gap[dep[u]]==0) break; 89 dep[u] = minn+1; 90 gap[dep[u]]++; 91 if(u!=start) u = edge[pre[u]^1].to; 92 } 93 } 94 return maxflow; 95 } 96 97 bool test(int mid) 98 { 99 tot = 0; 100 memset(head, -1, sizeof(head)); 101 for(int i = 0; i<uN; i++) 102 { 103 add(uN+vN, i, 1); 104 for(int j = 0; j<vN; j++) 105 if(maze[i][j]) 106 add(i, uN+j, 1); 107 } 108 for(int i = 0; i<vN; i++) 109 add(uN+i, uN+vN+1, mid); 110 111 int maxflow = sap(uN+vN, uN+vN+1, uN+vN+2); 112 return maxflow == uN; 113 } 114 115 char tmp[100000]; 116 int main() 117 { 118 while(scanf("%d%d", &uN, &vN) && (uN||vN)) 119 { 120 memset(maze, 0, sizeof(maze)); 121 getchar(); 122 for(int i = 0; i<uN; i++) 123 { 124 gets(tmp); 125 int j = 0, len = strlen(tmp); 126 while(tmp[j]!=‘ ‘ && j<len) j++; 127 j++; 128 for(int v = 0; j<=len; j++) 129 { 130 if(tmp[j]==‘ ‘||j==len) 131 { 132 maze[i][v] = 1; 133 v = 0; 134 } 135 else v = v*10+(tmp[j]-‘0‘); 136 } 137 } 138 139 int l = 1, r = uN; 140 while(l<=r) 141 { 142 int mid = (l+r)>>1; 143 if(test(mid)) 144 r = mid - 1; 145 else 146 l = mid + 1; 147 } 148 printf("%d\n", l); 149 } 150 }
POJ2289 Jamie's Contact Groups —— 二分图多重匹配/最大流 + 二分
标签:多重 getchar none ret contact eof sample hose using
原文地址:http://www.cnblogs.com/DOLFAMINGO/p/7821830.html