如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
输入输出格式
输入格式:
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)
输出格式:
一行,包含一个正整数,即为该网络的最大流。
输入输出样例
输入样例#1:
4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40
输出样例#1:
50
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,M<=25
对于70%的数据:N<=200,M<=1000
对于100%的数据:N<=10000,M<=100000
样例说明:
题目中存在3条路径:
4-->2-->3,该路线可通过20的流量
4-->3,可通过20的流量
4-->2-->1-->3,可通过10的流量(边4-->2之前已经耗费了20的流量)
故流量总计20+20+10=50。输出50。
一篇较好博文 :http://www.cnblogs.com/ShaneZhang/p/3755479.html
/* 网络最大流个人理解(并不透彻): 网络最大流是指网络中最大的可行流,可行流概念很好理解的。 增广路:简单来说就是指还可以有流量通过的路径。 求最大可行流可采用增广的算法:找出残量网络(还可增加流量), 即 容量-当前流量 和 一种逆向边(疑惑:逆向边 v-u的流量指u-v的初始当前流量还是0??) 所构成的网络, 每次找出增广路中的可行流量的min,将此增广路上的边进行增广(+min),直到不存在增广路。 至于建立逆向边(并不十分理解)才会使得已经增加了的流量回退,从而找到更大的可行流 (只要流量在满足网络流概念的情况下增加,则此时的网络中存在的一定是 更 优解)。 */ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #define ll long long using namespace std; const int N=300001; const int maxn=0x7fffff; inline int read() { int x=0;char c=getchar(); while(c<‘0‘||c>‘9‘)c=getchar(); while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar(); return x; } int head[N],dis[N]; bool vis[N]; int now=0; int n,m,S,T; struct node{ int u,v,cap,flow,nxt; }E[N]; inline void add(int u,int v,int w) { E[now].u=u; E[now].v=v; E[now].cap=w; E[now].flow=0; E[now].nxt=head[u]; head[u]=now++; } bool bfs(int start,int endd) { for(int i=1;i<=n;i++) dis[i]=-1; queue<int>Q; Q.push(start); dis[start]=0; while(!Q.empty()) { int topp=Q.front(); Q.pop(); for(int i=head[topp];~i;i=E[i].nxt) { if(dis[E[i].v]==-1&&E[i].cap>E[i].flow) { vis[E[i].v]=1; dis[E[i].v]=dis[topp]+1; Q.push(E[i].v); } } } if(dis[endd]==-1) return 0; return 1; } int dfs(int start,int minn) { if(start==T||minn<=0) return minn; int flow=0,f; for(int i=head[start];~i;i=E[i].nxt) { if(dis[start]+1==dis[E[i].v]&&E[i].cap-E[i].flow>0) { f=dfs(E[i].v,min(minn,E[i].cap-E[i].flow)); E[i].flow+=f; E[i^1].flow-=f; flow+=f; minn-=f; if(minn<=0) break; } } return flow; } inline void Dinic(int S,int T) { int ansflow=0; while(bfs(S,T)) ansflow+=dfs(S,maxn); printf("%d",ansflow); } int main() { n=read(),m=read(),S=read(),T=read(); for(int i=1;i<=n;i++) head[i]=-1; for(int i=1;i<=m;i++) { int u=read(),v=read(),w=read(); add(u,v,w); add(v,u,0); } Dinic(S,T); return 0; }