https://www.luogu.org/blog/ONE-PIECE/wang-lao-liu-jiang-xie-zhi-dinic
EK 292ms
#include <bits/stdc++.h> using namespace std; int n, m, s, t, cnt; int l, r; struct node { int to, nex, val; }E[200005]; int head[100005]; int vis[10005]; int que[10005]; struct no1 { int to, edge; }pre[10005]; bool bfs() { for(int i = 1; i <= r; i++) { vis[que[i]] = 0; pre[i].to = -1; pre[i].edge = -1; } l = 1, r = 0; vis[s] = 1; que[++r] = s; while(l <= r) { int u = que[l]; l++; for(int i = head[u]; i; i = E[i].nex) { int v = E[i].to; if(!vis[v] && E[i].val > 0) { pre[v].to = u; pre[v].edge = i; if(v == t) return true; vis[v] = 1; que[++r] = v; } } } return false; } int EK() { int res = 0; while(bfs()) { int mi = 1e9; for(int i = t; i != s; i = pre[i].to) { mi = min(mi, E[pre[i].edge].val); } for(int i = t; i != s; i = pre[i].to) { E[pre[i].edge].val -= mi; E[pre[i].edge ^ 1].val += mi; } res += mi; } return res; } int main() { scanf("%d%d%d%d", &n, &m, &s, &t); cnt = 1; for(int i = 1; i <= m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); E[++cnt].to = b; E[cnt].nex = head[a]; E[cnt].val = c; head[a] = cnt; E[++cnt].to = a; E[cnt].nex = head[b]; E[cnt].val = 0; head[b] = cnt; } printf("%d ", EK()); return 0; }
Dinic多路增广 + 弧优化 199ms
#include <bits/stdc++.h> using namespace std; int n, m, s, t, cnt; int maxflow; struct node { int to, nex, val; }E[200005]; int head[10005]; int cur[10005]; int dep[10005]; int inque[10005]; bool bfs() { for(int i = 1; i <= n; i++) cur[i] = head[i], dep[i] = 0x3f3f3f3f, inque[i] = 0; dep[s] = 0; queue<int> que; que.push(s); inque[s] = 1; while(!que.empty()) { int u = que.front(); que.pop(); inque[u] = 0; for(int i = head[u]; i; i = E[i].nex) { int v = E[i].to; if(E[i].val > 0 && dep[v] > dep[u] + 1) { dep[v] = dep[u] + 1; if(!inque[v]) { inque[v] = 1; que.push(v); } } } } if(dep[t] != 0x3f3f3f3f) return true; else return false; } int vis; int dfs(int x, int flow) { int rlow = 0; if(x == t) { vis = 1; maxflow += flow; return flow; } int used = 0; //当前使用了多少 for(int i = cur[x]; i; i = E[i].nex) { cur[x] = i; //更新弧 int v = E[i].to; if(E[i].val > 0 && dep[v] == dep[x] + 1) { if(rlow = dfs(v, min(flow - used, E[i].val))) { used += rlow; E[i].val -= rlow; E[i ^ 1].val += rlow; if(used == flow) break; //用完了 } } } return used; } void dinic() { int lowflow; while(bfs()) { vis = 1; while(vis) { vis = 0; dfs(s, 1000000000); } } } int main() { scanf("%d%d%d%d", &n, &m, &s, &t); cnt = 1; maxflow = 0; for(int i = 1; i <= m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); E[++cnt].to = b; E[cnt].nex = head[a]; E[cnt].val = c; head[a] = cnt; E[++cnt].to = a; E[cnt].nex = head[b]; E[cnt].val = 0; head[b] = cnt; } dinic(); printf("%d ", maxflow); return 0; }