标签:sed row closed positive ber travel struct cep his
题目链接:https://vjudge.net/problem/POJ-2112
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 18555 | Accepted: 6626 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
2 3 2 0 3 2 1 1 3 0 3 2 0 2 3 0 1 0 1 2 1 0 2 1 0 0 2 0
Sample Output
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 = 4e2+10; 17 18 int uN, vN, m, N, maze[MAXN][MAXN]; 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 memset(g, false, sizeof(g)); 46 for(int i = vN; i<N; i++) 47 for(int j = 0; j<vN; j++) 48 if(maze[i][j]<=mid) 49 g[i][j] = true; 50 51 for(int i = 0; i<vN; i++) 52 { 53 num[i] = m; 54 linker[i][0] = 0; 55 } 56 for(int u = vN; u<N; u++) 57 { 58 memset(used, false, sizeof(used)); 59 if(!dfs(u)) return false; 60 } 61 return true; 62 } 63 64 void Flyod() 65 { 66 for(int k = 0; k<N; k++) 67 for(int i = 0; i<N; i++) 68 for(int j = 0; j<N; j++) 69 maze[i][j] = min(maze[i][j], maze[i][k]+maze[k][j]); 70 } 71 72 int main() 73 { 74 while(scanf("%d%d%d", &vN, &uN, &m)!=EOF) 75 { 76 N = uN + vN; 77 for(int i = 0; i<N; i++) 78 for(int j = 0; j<N; j++) 79 { 80 scanf("%d", &maze[i][j]); 81 if(maze[i][j]==0) maze[i][j] = INF/2; 82 } 83 84 Flyod(); 85 int l = 1, r = 200*400; 86 while(l<=r) 87 { 88 int mid = (l+r)>>1; 89 if(hungary(mid)) 90 r = mid - 1; 91 else 92 l = mid + 1; 93 } 94 printf("%d\n", l); 95 } 96 }
最大流:
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 = 4e2+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, m, N, maze[MAXN][MAXN]; 25 int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN]; 26 void add(int u, int v, int w) 27 { 28 edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0; 29 edge[tot].next = head[u]; head[u] = tot++; 30 edge[tot].to = u; edge[tot].cap = 0; edge[tot].flow = 0; 31 edge[tot].next = head[v]; head[v] = tot++; 32 } 33 34 int sap(int start, int end, int nodenum) 35 { 36 memset(gap,0,sizeof(gap)); 37 memset(dep,0,sizeof(dep)); 38 memcpy(cur,head,sizeof(head)); 39 40 int u = start; 41 pre[u] = -1; 42 gap[0] = nodenum; 43 int maxflow = 0; 44 while(dep[start]<nodenum) 45 { 46 bool flag = false; 47 for(int i = cur[u]; i!=-1; i=edge[i].next) 48 { 49 int v = edge[i].to; 50 if(edge[i].cap-edge[i].flow && dep[v]+1==dep[u]) 51 { 52 flag = true; 53 cur[u] = pre[v] = i; 54 u = v; 55 break; 56 } 57 } 58 59 if(flag) 60 { 61 if(u==end) 62 { 63 int minn = INF; 64 for(int i = pre[u]; i!=-1; i=pre[edge[i^1].to]) 65 if(minn>edge[i].cap-edge[i].flow) 66 minn = edge[i].cap-edge[i].flow; 67 for(int i = pre[u]; i!=-1; i=pre[edge[i^1].to]) 68 { 69 edge[i].flow += minn; 70 edge[i^1].flow -= minn; 71 } 72 u = start; 73 maxflow += minn; 74 } 75 } 76 77 else 78 { 79 int minn = nodenum; 80 for(int i = head[u]; i!=-1; i=edge[i].next) 81 if(edge[i].cap-edge[i].flow && dep[edge[i].to]<minn) 82 { 83 minn = dep[edge[i].to]; 84 cur[u] = i; 85 } 86 gap[dep[u]]--; 87 if(gap[dep[u]]==0) break; 88 dep[u] = minn+1; 89 gap[dep[u]]++; 90 if(u!=start) u = edge[pre[u]^1].to; 91 } 92 } 93 return maxflow; 94 } 95 96 bool test(int mid) 97 { 98 tot = 0; 99 memset(head, -1, sizeof(head)); 100 for(int i = vN; i<N; i++) 101 { 102 add(N, i, 1); 103 for(int j = 0; j<vN; j++) 104 if(maze[i][j]<=mid) 105 add(i, j, 1); 106 } 107 for(int i = 0; i<vN; i++) 108 add(i, N+1, m); 109 110 int maxflow = sap(N, N+1, N+2); 111 return maxflow == uN; 112 } 113 114 void Flyod() 115 { 116 for(int k = 0; k<N; k++) 117 for(int i = 0; i<N; i++) 118 for(int j = 0; j<N; j++) 119 maze[i][j] = min(maze[i][j], maze[i][k]+maze[k][j]); 120 } 121 122 int main() 123 { 124 while(scanf("%d%d%d", &vN, &uN, &m)!=EOF) 125 { 126 N = uN + vN; 127 for(int i = 0; i<N; i++) 128 for(int j = 0; j<N; j++) 129 { 130 scanf("%d", &maze[i][j]); 131 if(maze[i][j]==0) maze[i][j] = INF/2; 132 } 133 134 Flyod(); 135 int l = 1, r = 200*400; 136 while(l<=r) 137 { 138 int mid = (l+r)>>1; 139 if(test(mid)) 140 r = mid - 1; 141 else 142 l = mid + 1; 143 } 144 printf("%d\n", l); 145 } 146 }
POJ2112 Optimal Milking —— 二分图多重匹配/最大流 + 二分
标签:sed row closed positive ber travel struct cep his
原文地址:http://www.cnblogs.com/DOLFAMINGO/p/7821843.html