【模板】ISAP最大流
题目描述
如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
输入输出格式
输入格式:
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)
输出格式:
一行,包含一个正整数,即为该网络的最大流。
输入输出样例
输入样例:
4 5 4 3
4 2 30
4 3 20
2 3 20
2 1 30
1 3 40
输出样例:
50
样例说明:
题目中存在3条路径:
4-->2-->3,该路线可通过20的流量
4-->3,可通过20的流量
4-->2-->1-->3,可通过10的流量(边4-->2之前已经耗费了20的流量)
故流量总计20+20+10=50。输出50。
说明
对于100%的数据:N<=10000,M<=100000
struct MaxFlow{ struct Edge{ int to,c,pre; }e[M]; int sz=1,S,T; int H[N],las[N],cur[N],gap[N]; void Add(int a,int b,int c){ e[++sz]=(Edge){b,c,las[a]}; las[a]=sz; e[++sz]=(Edge){a,0,las[b]}; las[b]=sz; } int ISAP(int x,int F,int usd=0){ if (x==T) return F; for (int i=cur[x],v;i;i=e[i].pre) if (e[i].c && H[v=e[i].to]+1==H[x]){ int f=ISAP(v,min(e[i].c,F-usd)); e[i].c-=f; e[i^1].c+=f; usd+=f; if (e[i].c) cur[x]=i; if (usd==F) return usd; } if (gap[H[x]]==1) H[S]=n+4; --gap[H[x]]; ++gap[++H[x]]; cur[x]=las[x]; return usd; } int Maxflow(int Ans=0){ while (H[S] < n+4) Ans+=ISAP(S,INF); return Ans; } }G;