P3376 【模板】网络最大流
https://www.luogu.com.cn/problem/P3376
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define int long long const int INF = 0x3f3f3f3f; const int maxn = 3e5+10; using namespace std; int m,u,w,v; struct edge { int v, c, nxt; } e[maxn<<1]; int s,t,n,head[maxn],q[maxn],level[maxn],tot; void add_edge(int u, int v, int c){ e[tot] = (edge){ v, c, head[u] }; head[u] = tot++; } //分层图 bool BFS(){ memset(level,0, sizeof(level)); q[1] = s; level[s] = 1; int hd = 0,tl = 1; while (hd != tl){ hd++; for(int i = head[q[hd]]; i != -1; i = e[i].nxt){ if(e[i].c && !level[e[i].v]){ tl++; level[e[i].v] = level[q[hd]] + 1; q[tl] = e[i].v; if (e[i].v == t) return true; } } } return false; } //增广路 int DFS(int f, int u){ if (u == t) return f; int d = 0, used = 0; for (int i = head[u];i != -1;i = e[i].nxt){ if (e[i].c && level[u] == level[e[i].v] - 1){ if ((d = DFS(min(f - used, e[i].c), e[i].v))){ e[i].c -= d; e[i ^ 1].c += d;//建立反向边 used += d;//这个点的最大流量 } } } if (!used) level[u] = 0; return used; } int Dinic(){ int max_flow = 0; while(BFS()){//判断汇点层次 int d = 0; while ((d = DFS(INF, s))) max_flow += d; } return max_flow; } signed main(){ //freopen("in","r",stdin); ios::sync_with_stdio(0); cin >> n >> m >> s >> t; memset(head, -1, sizeof(head)); for (int i = 1; i <= m; i++){ cin >> u >> v >> w; add_edge(u, v, w); add_edge(v, u, 0);//为什么是0? } cout << Dinic() << endl; return 0; }
1、裸的最大流
2、二分图的最大匹配:建一个点S,连到二分图的集合A中;建一个点T,连到二分图的集合B中。再将所有的集合A中的点与集合B中的点相连。全部边权设为1,跑一遍最大流,结果即为二分图的最大匹配
3、最小割:在单源单汇流量图中,最大流等于最小割
4、求最大权闭合图:最大权值=正点权之和-最小割