Dinic法求最大流
阿新 • • 發佈:2018-11-06
經過先對圖進行分層處理,我們在進行搜尋的時候 就會更加的舒服了
(當然 ,程式碼我省略了一版,這是最終形態了。。每條路也都是用結構體實現的)
#include <cstdio> #include <cstring> #include <queue> using namespace std; #define MAXN 210 #define INF 0x3f3f3f3f struct Edge { int st, ed;//開始 結束 int c;//權值 int next;//下一個節點 }edge[MAXN << 1]; int n, m; int s, t; int ans; int e = 0; int head[MAXN];//建立連結串列 int d[MAXN];//用來分層 void init() { int a, b, c; s = 1; t = m; e = 0; ans = 0; memset(head, -1, sizeof(head)); for(int i = 1; i <= n; i++)//建立一個 { scanf("%d%d%d", &a, &b, &c); edge[e].st = a; edge[e].ed = b; edge[e].c = c; edge[e].next = head[a]; head[a] = e++; edge[e].st = b; edge[e].ed = a; edge[e].next = head[b]; head[b] = e++; } } int bfs() { memset(d, -1, sizeof(d)); queue<int> q; d[s] = 0; q.push(s); int i; int cur; while(!q.empty())//BFS { cur = q.front(); q.pop(); for(i = head[cur]; i != -1; i = edge[i].next) { if(d[edge[i].ed] == -1 && edge[i].c > 0) { d[edge[i].ed] = d[cur] + 1; //對圖進行分層處理 q.push(edge[i].ed); } } } if(d[t] < 0) return 0; return 1; } int dinic(int x, int flow) { if(x == t) return flow; int i, a; for(i = head[x]; i != -1; i = edge[i].next) { if(d[edge[i].ed] == d[x] + 1 && edge[i].c > 0 && (a = dinic(edge[i].ed, min(flow, edge[i].c)))) //首先 要確保我們在搜尋時沒有走“回頭路” 而且可以到達終點,同時路是連通的 { edge[i].c -= a; edge[i ^ 1].c += a;//反向增加容量 異或運算取反 return a; } } return 0; } void solve()//這段寫的非常具有大牛風格 { while(scanf("%d%d", &n, &m) != EOF) { init(); while(bfs()) { int increment; increment = dinic(1, INF); ans += increment; //記錄總共的流量和(即最大流量) } printf("%d\n", ans); } } int main() { solve(); return 0; }