一.原题链接:http://poj.org/problem?id=1273
二.题目大意:直接给边给容量让你求最大流,模板得不能再模板了。
三.思路:没有思路,直接套模板,我自己打的好吧。注意有重边,还有多组测试数据。
四.代码:
1.EK
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <vector> #include <string> using namespace std; const int INF = 0x3f3f3f3f, MAX_N = 251, MAX_M = 208; int capacity[MAX_N][MAX_N], N, M, flow[MAX_N][MAX_N]; int EK() { int minFlow[MAX_N], preV[MAX_N], flag[MAX_N]; int i, j, s, t, save, cur, res; queue <int> que; while(1){ while(!que.empty()) que.pop(); memset(flag, -1, sizeof(flag)); memset(preV, -1, sizeof(preV)); que.push(1); s = 1, t = M; minFlow[1] = INF; while(!que.empty() && flag[t] == -1){ cur = que.front(); que.pop(); for(i = s; i <= t; i++){ save = capacity[cur][i] - flow[cur][i]; if(save > 0 && flag[i] == -1){ minFlow[i] = min(minFlow[cur], save); flag[i] = 0; que.push(i); preV[i] = cur; } } flag[cur] = 1; } if(flag[t] == -1) break; for(i = preV[t], j = t; i != -1; j = i, i = preV[i]){ flow[i][j] += minFlow[t]; flow[j][i] = -flow[i][j]; } } res = 0; for(i = s; i < t; i++) res += flow[i][t]; return res; } int main() { //freopen("in.txt", "r", stdin); int i, j, u, v, c; while(cin>>N>>M){ memset(flow, 0, sizeof(flow)); memset(capacity, 0, sizeof(capacity)); for(i = 0; i < N; i++){ cin>>u>>v>>c; capacity[u][v] += c; } cout<<EK()<<endl; } }
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <vector> #include <string> using namespace std; const int INF = 0x3f3f3f3f, MAX_N = 251, MAX_M = 208; int capacity[MAX_N][MAX_N], N, M, dist[MAX_N]; bool BFS() { int i, cur; queue <int> que; memset(dist, -1, sizeof(dist)); que.push(1); dist[1] = 0; while(!que.empty()){ cur = que.front(); que.pop(); for(i = 1; i <= M; i++) if(capacity[cur][i] > 0 && -1 == dist[i]){ dist[i] = dist[cur]+1; que.push(i); } } if(-1 == dist[M]) return false; return true; } int DFS(int s, int minflow) { int i, temp; if(s == M) return minflow; for(i = 1; i <= M; i++) if(dist[i] == dist[s] + 1 && capacity[s][i] > 0 && (temp = DFS(i, min(minflow, capacity[s][i])))){ capacity[s][i] -= temp; capacity[i][s] += temp; return temp; } return 0; } int main() { //freopen("in.txt", "r", stdin); int i, j, u, v, c, res, temp; while(cin>>N>>M){ memset(capacity, 0, sizeof(capacity)); for(i = 0; i < N; i++){ cin>>u>>v>>c; capacity[u][v] += c; } res = 0; while(BFS()){ while(temp = DFS(1, INF)) res += temp; } cout<<res<<endl; } }
3.预流推进(47ms)
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <vector> #include <string> using namespace std; const int INF = 0x3f3f3f3f, MAX_N = 251, MAX_M = 208; int RE[MAX_M][MAX_M], N, M, maxFlow, H[MAX_M], EF[MAX_M]; queue <int> que; void init() { memset(RE, 0, sizeof(RE)); memset(H, 0, sizeof(H)); memset(EF, 0, sizeof(EF)); maxFlow = 0; EF[1] = INF; EF[N] = -INF; H[1] = M; } void Push(int cur) { int i, temp; for(i = 1; i <= M; i++){ temp = min(EF[cur], RE[cur][i]); if(temp > 0 && (cur == 1 || H[cur] - H[i] == 1)){ RE[cur][i] -= temp, RE[i][cur] += temp; EF[cur] -= temp, EF[i] += temp; if(i == M) maxFlow += temp; if(i != M && i != 1) que.push(i); } } } void Relabel(int cur) { if(cur != 1 && cur != M && EF[cur] > 0){ H[cur]++; que.push(cur); } } void Push_Relabel() { int cur; que.push(1); while(!que.empty()){ cur = que.front(); que.pop(); Push(cur); Relabel(cur); } cout<<maxFlow<<endl; } int main() { //freopen("in.txt", "r", stdin); int i, j, u, v, c; while(cin>>N>>M){ init(); for(i = 0; i < N; i++){ cin>>u>>v>>c; RE[u][v] += c; } Push_Relabel(); } }
4,最高标号预流推进(32ms)
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <cstdlib> using namespace std; const int INF = 0x3f3f3f3f, MAX_SIZE = 251; class Push_Relabel { public: struct node { int x, h; bool friend operator <(const node &a,const node &b) { return a.h<b.h; } }; struct Edge { int v, weigt, next; }; Edge edges[MAX_SIZE*MAX_SIZE]; int s, t, maxFlow, cnt, head[MAX_SIZE], H[MAX_SIZE], EF[MAX_SIZE]; priority_queue <node> que; void init(int is, int it, int nodeNum) { memset(edges, 0, sizeof(edges)); memset(H, 0, sizeof(H)); memset(EF, 0, sizeof(EF)); memset(head, -1, sizeof(head)); maxFlow = 0; cnt = 0; s = is, t = it; EF[s] = INF; EF[t] = -INF; H[s] = nodeNum; } void addEdge(int u, int v, int weight) { edges[cnt] = (Edge){v, weight, head[u]}; head[u] = cnt++; edges[cnt] = (Edge){u, 0, head[v]}; head[v] = cnt++; } void Push(int cur) { int i, temp, v; node tmp; for(i = head[cur]; i != -1; i = edges[i].next){ v = edges[i].v; temp = min(edges[i].weigt, EF[cur]); if(temp > 0 &&(cur == s || 1==H[cur]-H[v])){ edges[i].weigt -= temp, edges[i^1].weigt += temp; EF[cur] -= temp, EF[v] += temp; if(v == t) maxFlow += temp; if(v != s && v != t){ tmp.x = v, tmp.h = H[v]; que.push(tmp); } } } } void Relabel(int cur) { node tmp; if(cur != s && cur != t && EF[cur] > 0){ H[cur]++; tmp.h = H[cur], tmp.x = cur; que.push(tmp); } } int ans() { node cur{s, H[s]}; que.push(cur); while(!que.empty()){ cur = que.top(); que.pop(); Push(cur.x); Relabel(cur.x); } return maxFlow; } }; int nodeNum, edgeNum; int getAns(int s, int t, int nodeNum) { int i, j, u, v, c; Push_Relabel G; G.init(s, t, nodeNum); while(edgeNum--){ cin>>u>>v>>c; G.addEdge(u, v, c); } return G.ans(); } int main() { //freopen("in.txt", "r", stdin); while(cin>>edgeNum>>nodeNum){ cout<<getAns(1, nodeNum, nodeNum)<<endl; } }