[Luogu] P3376 模板-网络流-最大流
题目描述
如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
输入输出格式
输入格式:
第一行包含四个正整数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。
分析
这是一个单纯的题目,优化都不用
= =然而我是对着刘汝佳写过去的
网络流还是推荐紫书
代码
1 //事先声明,这份代码并不是原创,只是将刘汝佳的进行风格转化 2 //数组模拟版本邻接表= =刘汝佳写的虽然简练但是我不是很习惯 3 #include<cstdio> 4 #include<iostream> 5 #include<queue> 6 #include<cstring> 7 #define maxn 10000000 8 using namespace std; 9 10 int inf = 2139999999; 11 12 struct edge{ 13 int from,u,v,cup,flow; 14 }e[maxn]; 15 16 int tot = 2,first[maxn*4]; 17 void insert(int u,int v,int ccup){ 18 e[tot].from = first[u]; 19 e[tot].u = u; 20 e[tot].v = v; 21 e[tot].cup = ccup; 22 e[tot].flow = 0; 23 first[u] = tot; 24 tot++; 25 26 e[tot].from = first[v]; 27 e[tot].u = v; 28 e[tot].v = u; 29 e[tot].cup = e[tot].flow = 0; 30 first[v] = tot; 31 tot++; 32 } 33 34 int pre[maxn],s,t,a[maxn],n,m; 35 int maxflow(int s,int t){ 36 37 int flow = 0; 38 while(true){ 39 // cout << "gua! "; 40 memset(a,0,sizeof(a)); 41 queue<int> Q; 42 Q.push(s); 43 a[s] = inf; 44 while(!Q.empty()){ 45 // cout << "Meow! "; 46 int p = Q.front(); Q.pop(); 47 48 for(int i = first[p];i;i = e[i].from){ 49 edge &E = e[i]; 50 if(!a[E.v] && E.flow < E.cup){ 51 pre[E.v] = i; 52 a[E.v] = min(a[p],E.cup-E.flow); 53 Q.push(E.v); 54 } 55 } 56 57 if(a[t]) break; 58 } 59 60 if(!a[t]) break; 61 62 for(int u = t;u != s;u = e[pre[u]].u){ 63 e[pre[u]].flow += a[t]; 64 e[pre[u]^1].flow -= a[t]; 65 } 66 67 flow += a[t]; 68 } 69 70 // for(int i = 0;i <= n;i++){ 71 // printf("%d ",a[i]); 72 // }cout << endl; 73 74 return flow; 75 } 76 77 int main(){ 78 scanf("%d%d%d%d",&n,&m,&s,&t); 79 80 for(int i = 1;i <= m;i++){ 81 int u,v,ccup; 82 scanf("%d%d%d",&u,&v,&ccup); 83 insert(u,v,ccup); 84 } 85 86 cout << maxflow(s,t); 87 88 // for(int i = 0;i <= tot;i++){ 89 // printf("%d %d %d %d %d\n",e[i].from,e[i].u,e[i].v,e[i].cup,e[i].flow); 90 // } 91 92 return 0; 93 }
转载请注明出处 -- 如有意见欢迎评论