Drainage Ditches [HDU1532]

24 篇文章 0 订阅
1 篇文章 0 订阅

AC通道:http://acm.hdu.edu.cn/showproblem.php?pid=1532


Drainage Ditches


Description

在农夫 John 的农场上,每逢下雨, Bessie 最喜欢的三叶草地就积聚了一潭水。
这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。
因此,农夫 John 修建了一套排水系统来使 Bessie 的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。
作为一名一流的技师,农夫 John 已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。

农夫 John 知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。
需要注意的是,有些时候从一处到另一处不只有一条排水沟。

根据这些信息,计算从水潭排水到小溪的最大流量。
对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。


Input

1 行: 两个用空格分开的整数 N(0N200) M(2M200)
N 是农夫 John 已经挖好的排水沟的数量, M 是排水沟交叉点的数量。
交点 1 是水潭,交点 M 是小溪。

2 行到第 N+1 行: 每行有三个整数, Si,Ei Ci
Si Ei (1Si,EiM) 指明排水沟两端的交点,雨水从 Si 流向 Ei
Ci(0Ci10,000,000) 是这条排水沟的最大容量。


Output

输出一个整数,即排水的最大流量。


Sample Input

5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10


Sample Output

50


Solution

总算开始学网络流了,心情有点激动啊!!
综上,这是一道模板题(但HDU的多组数据坑死我了)。
不多说,上代码。


Code

[cpp]
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <cstring>  
  4. #include <queue>  
  5.   
  6. using namespace std;  
  7.   
  8. const int MAXN=1000;  
  9.   
  10. int n,m,cnt,s=1,t;  
  11. queue<int>q;  
  12.   
  13. int weight[MAXN*2],data[MAXN*2];  
  14. int head[MAXN],cur[MAXN],nxt[MAXN*2],dis[MAXN];  
  15.   
  16. inline int Min(int x,int y){  
  17.     return x<y?x:y;  
  18. }  
  19.   
  20. inline int Max(int x,int y){  
  21.     return x>y?x:y;  
  22. }  
  23.   
  24. void add(int x,int y,int z){  
  25.     nxt[cnt]=head[x];data[cnt]=y;weight[cnt]=z;head[x]=cnt++;  
  26.     nxt[cnt]=head[y];data[cnt]=x;weight[cnt]=0;head[y]=cnt++;  
  27. }  
  28.   
  29. bool BFS(){  
  30.     memset(dis,-1,sizeof dis);  
  31.     dis[1]=0;  
  32.     q.push(1);  
  33.     while(!q.empty()){  
  34.         int now=q.front();  
  35.         q.pop();  
  36.         for(int i=head[now];i!=-1;i=nxt[i])  
  37.             if(weight[i]&&dis[data[i]]<0){  
  38.                 dis[data[i]]=dis[now]+1;  
  39.                 q.push(data[i]);  
  40.             }  
  41.     }  
  42.     if(dis[n]==-1)return false;  
  43.     return true;  
  44. }  
  45.   
  46. int dfs(int now,int flow){  
  47.     if(now==n)return flow;  
  48.     int Low;  
  49.     for(int &i=cur[now];i!=-1;i=nxt[i]){  
  50.         if(weight[i]&&dis[data[i]]==dis[now]+1){  
  51.             Low=dfs(data[i],Min(flow,weight[i]));  
  52.             if(Low){  
  53.                 weight[i]-=Low;  
  54.                 weight[i^1]+=Low;  
  55.                 return Low;  
  56.             }  
  57.         }  
  58.     }  
  59.     return 0;  
  60. }  
  61.   
  62. int main(){  
  63.     while(scanf(“%d%d”,&m,&n)!=EOF){  
  64.         cnt=0;  
  65.         for(int i=1;i<=n;i++)head[i]=-1,weight[i]=nxt[i]=0;  
  66.         if(n==0){printf(“0\n”);continue;}  
  67.         for(int i=1;i<=m;i++){  
  68.             int x,y,z;  
  69.             scanf(”%d%d%d”,&x,&y,&z);  
  70.             add(x,y,z);  
  71.         }  
  72.         int sum=0,flow;  
  73.         while(BFS()){  
  74.             memcpy(cur,head,sizeof head);  
  75.             while(flow=dfs(1,0x3f3f3f3f))sum+=flow;  
  76.         }  
  77.         printf(”%d\n”,sum);  
  78.     }  
  79.     return 0;  
  80. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值