最大流dinic算法板子
FZSZ Online Judge #334. 最大流
题目描述
这是一道网络流模板题。
你需要求出点1到点n的最大流。
本题时限2s,空间限制512M(大概相当于正常机子4s)
数据已更新
输入格式
输入第一行为两个正整数n和m。
以下m行每行三个正整数ai、bi、ci,表示ai到bi有一条容量为ci的单向边。
输出格式
一行输出最大流。
输入样例
2 1
1 2 3
输出样例
3
数据范围
1≤n≤3000,1≤m≤200000,1≤ai,bi≤n,0≤ci≤1000。
#include<cmath> #include<cstdio> #include<cstring> #include<string> #include<iostream> #include<algorithm> #include<queue> #define TOTAL_EDGE 400011 #define TOTAL_POINT 6011 #define INF 2147483647 #define cmin(a,b) a<b?a:b #define FOR(i,s,t) for(register int i=s;i<=t;++i) struct Max_Flow{ int n,m,tot,x,y,z,S,T; int nxt[TOTAL_EDGE],las[TOTAL_POINT],to[TOTAL_EDGE],c[TOTAL_EDGE],dep[TOTAL_POINT]; std::queue<int>q; int read(){ char c=getchar(); while(c<'0'||c>'9') c=getchar(); int data=0; while(c>='0'&&c<='9') data=(data<<1)+(data<<3)+c-'0',c=getchar(); return data; } void add(int x,int y,int z){ nxt[++tot]=las[x]; las[x]=tot; to[tot]=y; c[tot]=z; } void adde(int x,int y,int z){ add(x,y,z); add(y,x,0); } void init(){ tot=1; n=read(); m=read(); FOR(i,1,m){ x=read(); y=read(); z=read(); adde(x,y,z); } S=1; T=n; } int bfs(){ FOR(i,S,T) dep[i]=0; dep[1]=1; q.push(1); int now; while(!q.empty()){ now=q.front(); q.pop(); for(register int e=las[now];e;e=nxt[e]) if(c[e]>0&&!dep[to[e]]){ dep[to[e]]=dep[now]+1; q.push(to[e]); } } return dep[T]; } int dfs(int now,int flow){ if(now==T) return flow; int ret=0,d; for(register int e=las[now];e&&flow;e=nxt[e]) if(c[e]>0&&dep[to[e]]==dep[now]+1){ d=dfs(to[e],cmin(flow,c[e])); c[e]-=d; c[e^1]+=d; flow-=d; ret+=d; } if(!ret) dep[now]=0; return ret; } void dinic(){ int ans=0; while(bfs()) ans+=dfs(S,INF); printf("%d\n",ans); } void work(){ init(); dinic(); } }max_flow; int main(){ max_flow.work(); return 0; }