零崎的悠哉日常Ⅱ
题目来源:https://biancheng.love/contest-ng/index.html#/34/problems
题目描述
零崎闲下来的时候很喜欢去看书,特别是在沙河的时候,经常和社团的小伙伴一起去自习室看小说。教学楼跑的次数多了,自然对路也比较熟,比如教三大教室旁边的楼梯间里或者教学楼连通走廊的制图教室外经常有妹子读英语什么的……
说起来教室之间有各种各样不同的路可以走,不同的路的容纳量也不同,那么这么多教室这么多路,如果从一间教室前往另一间教室上课,最多可以有多少人一起走呢?零崎虽然对路和每条路的容量很熟,不过教室这么多,路太多了怎么算得清呢?
输入
多组输入数据。每组数据N+1+T行。
第一行为三个整数,教室数V,路的数量N和查询数量T。
接下来N行每行三个整数s,t,c为一条教室s到t容量为c的路。
最后T行每行两个整数x,y为查询的教室编号。
输出
每组样例输出T行,每次查询一行,为x,y间通路的最大流量。
输入样例
5 7 2
1 2 10
1 4 2
2 4 6
2 3 6
3 4 3
3 5 8
4 5 5
1 5
4 2
输出样例
11
0
解题思路:
最大流问题的处理。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAX_V=1010; 5 const int INF=99999999; 6 const double eps = 1e-8; 7 8 //用于表示边的结构体(终点、容量、反向边) 9 struct edge 10 { 11 int to,cap,rev; 12 }; 13 14 vector<edge> G[MAX_V];//图的邻接表表示,注意是NMAX个数组 15 bool used[MAX_V]; //DFS中用到的访问标记 16 17 //向图中增加一条从s到t容量为cap的边 18 void add_edge(int from,int to,int cap) 19 { 20 edge a = {to,cap,G[to].size()}; 21 edge b = {to,cap,G[to].size()}; 22 G[from].push_back(a); 23 G[to].push_back(b); 24 } 25 26 //通过DFS寻找增广路 27 int dfs(int v,int t,int f) 28 { 29 if(v==t)return f; 30 used[v]=true; 31 for(int i=0; i<G[v].size(); i++) 32 { 33 edge &e=G[v][i]; 34 if(!used[e.to]&&e.cap>0) 35 { 36 int d=dfs(e.to,t,min(f,e.cap)); 37 if(d > 0) 38 { 39 e.cap -= d; 40 G[e.to][e.rev].cap += d; 41 return d; 42 } 43 } 44 } 45 return 0; 46 } 47 48 //求解从s到t的最大流 49 int max_flow(int s,int t) 50 { 51 int flow=0; 52 while(1) 53 { 54 memset(used,0,sizeof(used)); 55 int f=dfs(s,t,INF); 56 if(f==0) 57 return flow; 58 flow += f; 59 } 60 } 61 62 int main() 63 { 64 int s,t,c,v,n,T,res; 65 while(scanf("%d%d%d",&v,&n,&T)==3) 66 { 67 for(int i=0;i<MAX_V;i++) 68 G[i].clear(); 69 while(n--) 70 { 71 scanf("%d%d%d",&s,&t,&c); 72 add_edge(s,t,c); 73 } 74 while(T--) 75 { 76 scanf("%d%d",&s,&t); 77 res=max_flow(s,t); 78 printf("%d\n",res); 79 } 80 } 81 return 0; 82 }
作者: 伊甸一点
出处: http://www.cnblogs.com/zpfbuaa/
本文版权归作者伊甸一点所有,欢迎转载和商用(须保留此段声明),且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
原文链接 如有问题, 可邮件(zpflyfe@163.com)咨询.