標籤:sde sdc recv ddd opd tgt meta space post
題目:題目描述
有 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>using namespace 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)