1. 程式人生 > 實用技巧 >Dinic演算法求解最大流問題

Dinic演算法求解最大流問題

題目:luogu 3376

分析:用Dinic演算法求解最大流問題,複雜度為$O(mn^{2})$. 核心有兩部分:利用BFS構造level graph, 然後用DFS找增廣路徑。程式碼如下,難點在於函式DFS(start, flow), 返回從結點start出發到$t$的最大流,並且滿足流值不超過flow.

#include<iostream>
#include<queue>
#include<algorithm>
#include<string.h>
using namespace std;
//n<=200, m<=5000, w<=2^31-1 (int)
int utoe[205];//結點u對應的邊e的編號 int level[205];//每個結點的level number long long INF = 429496729400; int s, t; long long maxflow; struct { long long cap;//邊的容量 int toVer;//邊(u,v)對應的v int nex;//邊(u,v1)上一條共起點的邊(u,v2)的編號 } edge[10005]; bool constructLG()//構造level graph { queue<int>q; memset(level, -1, sizeof
(level));//每個結點的level初始化為-1 int e_idx;//邊的編號 int top_ele;//隊首元素(結點編號) int v_temp; q.push(s); level[s] = 0; while (!q.empty()) { top_ele = q.front(); q.pop(); e_idx=utoe[top_ele]; while (e_idx >= 0) { v_temp = edge[e_idx].toVer;
if (edge[e_idx].cap > 0 && level[v_temp] == -1) { q.push(v_temp); level[v_temp] = level[top_ele] + 1; if (v_temp == t) return true; } e_idx = edge[e_idx].nex; } } return false; } long long DFS(int start, long long flow)//flow是為結點start分配的flow value { long long res = 0; long long subflow; if (start == t) return flow; int e_idx=utoe[start]; int v_temp; while (e_idx>=0 && flow>0)//flow如果為零,沒必要再搜尋下去 { v_temp = edge[e_idx].toVer; if (level[v_temp] == level[start] + 1 && edge[e_idx].cap > 0) { subflow=DFS(v_temp,min(flow,edge[e_idx].cap)); if (subflow == 0)//剪枝 level[v_temp] = -1; edge[e_idx].cap -= subflow; edge[e_idx ^ 1].cap += subflow; res += subflow; flow -= subflow; } e_idx = edge[e_idx].nex; } return res; } void Dinic() { while (constructLG()) maxflow+=DFS(s, INF); } int main() { int n, m; int u, v, c; int id_e; int i; while (scanf("%d%d%d%d", &n, &m, &s, &t) == 4) { id_e = -1; memset(utoe, -1, sizeof(utoe)); for (i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &c); edge[++id_e].cap = c; edge[id_e].toVer = v; edge[id_e].nex = utoe[u]; utoe[u] = id_e; edge[++id_e].cap = 0; edge[id_e].toVer = u; edge[id_e].nex = utoe[v]; utoe[v] = id_e; } maxflow = 0; Dinic(); printf("%lld\n", maxflow); } return 0; }
View Code