HDU-3549-Flow Problem
阿新 • • 發佈:2019-03-17
-- std ear algo 沒有 最大 [1] memory 算法
鏈接:https://vjudge.net/problem/HDU-3549
題意:
給定多張圖,求從1到n的最大流
思路:
網絡流最大流
增廣路算法,具體看註釋。
代碼:
#include <iostream> #include <memory.h> #include <vector> #include <map> #include <algorithm> #include <cstdio> #include <math.h> #include <queue> #include <string> using namespace std; typedef long long LL; const int MAXM = 1000 + 10; const int MAXN = 20; const int INF = 1e9 + 10; int n, m; struct Edge { int _from, _to, _cap, _flow; Edge(int from, int to, int cap, int flow):_from(from), _to(to), _cap(cap), _flow(flow){}; }; vector<Edge> edges;//記錄每條邊 vector<int> G[MAXN];//記錄圖,每個節點的邊 int a[MAXN], p[MAXN]; //a數組記錄每次找增廣路時候每個節點對應能加的流 //p數組記錄流經的點對應的線路的編號 void Init() { edges.clear(); for (int i = 0;i < n;i++) G[i].clear(); } int Solve() { int flow = 0;//總流量 while (1) { memset(a, 0, sizeof(a));//每次找增廣路初始化 queue<int> que;//每次bfs的隊列 que.push(1); a[1] = INF; while (!que.empty()) { int x = que.front(); que.pop(); for (int i = 0;i < G[x].size();i++) { Edge & e = edges[G[x][i]]; if (!a[e._to] && e._cap > e._flow) { //a為0表示沒有流過這個點同時流量小於容量 p[e._to] = G[x][i]; a[e._to] = min(a[x], e._cap - e._flow); //能流的流量是線路最大流量和上一個節點的值中的較小值 que.push(e._to);//新節點進隊 } } if (a[n] > 0)//如果流到了終點,break break; } if (a[n] == 0)//如果終點流不到,表示增廣路找不到, break; for (int u = n;u != 1;u = edges[p[u]]._from) { edges[p[u]]._flow += a[n]; edges[p[u] ^ 1]._flow -= a[n];//表示與正向對應的反向的邊 } flow += a[n]; } return flow; } int main() { int t; int l, r, c, cnt = 0; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); Init(); for (int i = 1;i <= m;i++) { scanf("%d%d%d", &l, &r, &c); edges.push_back(Edge(l, r, c, 0)); edges.push_back(Edge(r, l, 0, 0));//增加反向邊 保證能找到最大流 G[l].push_back(edges.size() - 2); G[r].push_back(edges.size() - 1); } cout << "Case " << ++cnt << ": "; cout << Solve() << endl; } return 0; }
HDU-3549-Flow Problem