洛谷 P3376 模板网络最大流 题解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P3376 模板网络最大流 题解相关的知识,希望对你有一定的参考价值。
此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。
题目链接:https://www.luogu.org/problemnew/show/3376
题目描述
如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
输入输出格式
输入格式:第一行包含四个正整数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。
最近学了一下网络流,写个dinic板子ww感谢@ytez jzw的模板
AC代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 6 const int MAXN = 100005; 7 const int INF = 1e9; 8 inline void read(int &x) 9 { 10 char ch = getchar(),c = ch;x = 0; 11 while(ch < ‘0‘ || ch > ‘9‘) c = ch,ch = getchar(); 12 while(ch <= ‘9‘ && ch >= ‘0‘) x = (x<<1)+(x<<3)+ch-‘0‘,ch = getchar(); 13 if(c == ‘-‘) x = -x; 14 } 15 16 int n,m,s,t,u,v,w,cnt,ans,l,r; 17 int head[MAXN<<2],depth[MAXN],q[MAXN]; 18 19 inline int Min(int a,int b) 20 {return a<b?a:b;} 21 22 inline int other(int x) 23 {return (x%2==0)?(x-1):(x+1);} 24 25 struct Edge 26 { 27 int f,t,val,nxt; 28 }e[MAXN<<2]; 29 30 void insert(int f,int t,int v) 31 { 32 e[++cnt].f = f,e[cnt].t = t; 33 e[cnt].val = v,e[cnt].nxt = head[f]; 34 head[f] = cnt; 35 } 36 37 bool bfs() 38 { 39 memset(depth,-1,sizeof(depth)); 40 l = 1,r = 1; 41 q[++r] = s,depth[s] = 0; 42 while(l <= r) 43 { 44 int now = q[l++]; 45 if(now == t) continue; 46 for(int i = head[now];i;i = e[i].nxt) 47 { 48 if(!e[i].val) continue; 49 int to = e[i].t; 50 if(depth[to] == -1) 51 { 52 depth[to] = depth[now]+1; 53 q[++r] = to; 54 } 55 } 56 } 57 return depth[t] != -1; 58 } 59 60 int dfs(int now,int flow) 61 { 62 if(now == t) return flow; 63 int flowed = 0; 64 for(int i = head[now];i;i = e[i].nxt) 65 { 66 int to = e[i].t; 67 if(flow == flowed) break; 68 if(e[i].val == 0) continue; 69 70 if(depth[to] == depth[now]+1) 71 { 72 int new_flow = dfs(to,Min(e[i].val,flow-flowed)); 73 flowed += new_flow; 74 e[i].val -= new_flow; 75 e[other(i)].val += new_flow; 76 } 77 } 78 79 return flowed; 80 } 81 82 int main() 83 { 84 read(n),read(m); 85 read(s),read(t); 86 for(int i = 1;i <= m;++ i) 87 { 88 read(u),read(v),read(w); 89 insert(u,v,w); 90 insert(v,u,0); 91 } 92 while(bfs()) 93 ans += dfs(s,INF); 94 95 printf("%d\n",ans); 96 return 0; 97 }
更新*1 运行速度688ms --> 252ms
以上是关于洛谷 P3376 模板网络最大流 题解的主要内容,如果未能解决你的问题,请参考以下文章