标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 70451 | Accepted: 27391 |
5 4 1 2 40 1 4 20 2 4 20 2 3 30 3 4 10
50
最大流入门题,裸的Edmonds-Karp。
1 //2016.9.22 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #define N 205 7 8 using namespace std; 9 10 const int inf = 0x3f3f3f3f; 11 12 struct Edge 13 { 14 int from, to , cap, flow;//分别为边的两个端点、容量、边上的流 15 Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f){} 16 }; 17 18 struct EdmondsKarp//Edmonds-Karp算法 19 { 20 int n, m;//结点编号0——n-1 21 vector<Edge> edges;//存边与反向弧 22 vector<int> G[N];//邻接表,G[i][j]表示结点i的第j条边在数组edges中的序号 23 int a[N];//当起点到i的可改进量 24 int p[N];//最短路树上p的入弧编号 25 26 void init(int n)//初始化 27 { 28 for(int i = 0; i < n; i++)G[i].clear(); 29 edges.clear(); 30 } 31 32 void addEdge(int from, int to, int cap)//添加边 33 { 34 edges.push_back(Edge(from, to, cap, 0)); 35 edges.push_back(Edge(to, from, 0, 0));//反向弧 36 m = edges.size(); 37 G[from].push_back(m-2);//加入编号 38 G[to].push_back(m-1); 39 } 40 41 int maxFlow(int s, int t)//最大流,s为源点,t为汇点 42 { 43 int flow = 0; 44 while(1) 45 { 46 memset(a, 0, sizeof(a)); 47 queue<int> Q; 48 Q.push(s); 49 a[s] = inf; 50 while(!Q.empty()) 51 { 52 int x = Q.front(); Q.pop(); 53 for(int i = 0; i < G[x].size(); i++) 54 { 55 Edge& e = edges[G[x][i]]; 56 if(!a[e.to] && e.cap>e.flow) 57 { 58 p[e.to] = G[x][i]; 59 a[e.to] = min(a[x], e.cap-e.flow); 60 Q.push(e.to); 61 } 62 } 63 if(a[t])break; 64 } 65 if(!a[t])break;//残余网络中不存在增广路,当前流是最大流 66 for(int u = t; u != s; u = edges[p[u]].from)//找到一条增广路 67 { 68 edges[p[u]].flow += a[t]; 69 edges[p[u]^1].flow -= a[t];//p[u]^1为p[u]的反向边 70 } 71 flow += a[t]; 72 } 73 return flow; 74 } 75 }; 76 77 int main() 78 { 79 int n, m; 80 EdmondsKarp e; 81 while(scanf("%d%d", &m, &n)!=EOF) 82 { 83 int u, v, c; 84 e.init(n); 85 for(int i = 0; i < m; i++) 86 { 87 scanf("%d%d%d", &u, &v, &c); 88 u--, v--; 89 e.addEdge(u, v, c); 90 } 91 printf("%d\n", e.maxFlow(0, n-1)); 92 } 93 94 return 0; 95 }
标签:
原文地址:http://www.cnblogs.com/Penn000/p/5896594.html