算法復習——網絡流模板(ssoj)
阿新 • • 發佈:2017-07-02
ddd tde res csr dpf ada spi gyp clj
題目:
題目描述
有 n(0<n<=1000)個點,m(0<m<=1000)條邊,每條邊有個流量 h(0<=h<35000),求從點 start 到點 end 的最大流。
輸入格式
第一行:4 個整數,分別是 n,m,start,end 。
接下來有 m 行,每行四個三個整數 a,b,h,分別表示 a 到 b,流量為 h 的一條邊。
輸出格式
輸出從點 start 到點 end 的最大流。
樣例數據 1
輸入 [復制]
7 14 1 7
1 2 5
1 3 6
1 4 5
2 3 2
2 5 3
3 2 2
3 4 3
3 5 3
3 6 7
4 6 5
5 6 1
6 5 1
5 7 8
6 7 7
輸出
14
備註
【樣例圖示】
【數據範圍】
0<n,m<=1000;h<=35000
方法:
網絡流基礎模板
代碼:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> #include<queue> usingnamespace std; queue<int>que; const int N=100005; const int inf=1e+9; int first[N],go[N*2],next[N*2],rest[N*2],lev[N],tot=1; int n,m,src,des,ans; inline bool bfs() { for(int i=1;i<=n;i++) lev[i]=-1; int tail,head,que[N]; que[tail=1]=src; lev[src]=0; for(head=1;head<=tail;head++) {int u=que[head],v; for(int e=first[u];e;e=next[e]) { if(rest[e]&&lev[v=go[e]]==-1) { lev[v]=lev[u]+1; que[++tail]=v; if(v==des) return true; } } } return false; } inline int dinic(int u,int flow) { if(u==des) return flow; int res=0,temp,v; for(int e=first[u];e;e=next[e]) { if(rest[e]&&lev[v=go[e]]>lev[u]) { temp=dinic(v,min(rest[e],flow-res)); if(temp) { res+=temp; rest[e]-=temp,rest[e^1]+=temp; if(res==flow) break; } } } if(res!=flow) lev[u]=-1; return res; } inline void comb(int u,int v,int w) { next[++tot]=first[u],first[u]=tot,rest[tot]=w,go[tot]=v; next[++tot]=first[v],first[v]=tot,rest[tot]=0,go[tot]=u; } inline void maxflow() { while(bfs()) ans+=dinic(src,inf); } int main() { //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); scanf("%d%d%d%d",&n,&m,&src,&des); int u,v,w; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); comb(u,v,w); } maxflow(); cout<<ans<<endl; return 0; }
算法復習——網絡流模板(ssoj)