Drainage Ditches 草地排水 usaco 4.2.1

描述

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

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

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

格式

PROGRAM NAME:ditch

INPUT FORMAT:

(file ditch.in)

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

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

OUTPUT FORMAT:

(file ditch.out)

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

SAMPLE INPUT

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

SAMPLE OUTPUT

50

EK算法和dinic最大流。
 1 /*
 2  ID:10239512
 3  PROG:ditch
 4  LANG:C++    
 5     */ 
 6 //#include <iostream> 
 7 #include<fstream>
 8 #include<cstring>
 9 using namespace std;
10 ifstream cin("ditch.in");
11 ofstream cout("ditch.out");
12 int n,m;
13 int cf[201][201]={0};
14 int pre[201];int ans=0;
15 int q[1000];  
16 
17 int main()
18 {
19     cin>>n>>m;
20     for(int i=1;i<=n;++i)
21     {
22      int s,t,w;
23      cin>>s>>t>>w;
24      cf[s][t]+=w;
25             }
26     bool flag=1;
27     q[1]=1;
28     while(flag)
29     {
30      flag=0;
31      memset(pre,0,sizeof(pre));
32      int h=0,t=1;
33      
34      while(h<t)
35      {
36       h++;
37       for(int i=2;i<=m;++i)
38       if(pre[i]==0&&cf[q[h]][i]>0)
39       {
40        pre[i]=q[h];
41        if(i==m) {flag=1;break;}
42        q[++t]=i;
43               }
44       if(flag) break; 
45                 }
46       if(flag)
47       {
48        int v1=m;
49        int mimi=0xffffff;
50        while(v1!=1)
51        {
52         mimi=min(mimi,cf[pre[v1]][v1]);
53         v1=pre[v1]; 
54                     }
55        v1=m; 
56        ans+=mimi;
57        while(v1!=1)
58        {
59         cf[pre[v1]][v1]-=mimi;
60         cf[v1][pre[v1]]+=mimi;
61         v1=pre[v1];
62                    }
63               }
64                }    
65     
66      cout<<ans<<endl;
67      return 0;
68     }
 1 /*
 2  ID:10239512
 3  PROG:ditch
 4  LANG:C++    
 5     */
 6 #include<fstream>
 7 #include<cstring> 
 8 #define Max_int 0xffffff
 9 #define M 201
10 using namespace std;
11 ifstream cin("ditch.in");
12 ofstream cout("ditch.out");
13 
14 int n,m,s,t;
15 int lin[M][M],cf[M][M],d[M],ans[M];
16 
17 int Dinic(){
18     int q[M];
19     memset(q,0,sizeof(q));
20     for(int i=1;i<=m;++i) d[i]=Max_int;
21     q[1]=s; d[s]=0; int len=1;
22     for(int i=1;i<=len;++i)
23     {
24      int node=q[i];
25      for(int j=1;j<=ans[node];++j)
26      {
27       int next=lin[node][j];
28       if(cf[node][next]&&d[node]+1<d[next])
29       {
30        q[++len]=next;
31        d[next]=d[node]+1;
32        if(next==t) return 1;                     
33                                                              }       
34              }
35             }
36     return 0;
37     }
38 
39 int find(int num,int ccf){
40     if(ccf==0) return 0;
41     if(num==t) return ccf;
42     
43     for(int i=1;i<=ans[num];++i)
44     {
45      int next=lin[num][i],sum=0;
46      if(d[next]==d[num]+1&&(sum=find(next,min(ccf,cf[num][next]))))
47      {
48       cf[num][next]-=sum;
49       cf[next][num]+=sum;
50       return sum;
51                                                                                    }       
52             }
53     return 0;
54     }
55 
56 
57 int main()
58 {
59     cin>>n>>m;
60     s=1,t=m;
61     for(int i=1;i<=n;++i)
62     {
63      int x,y,w;cin>>x>>y>>w;
64      lin[x][++ans[x]]=y;
65      cf[x][y]+=w;
66      lin[y][++ans[y]]=x;
67             }
68 
69     int tot=0,ccf=0;
70     while(Dinic())
71     while(ccf=find(s,Max_int))
72     tot+=ccf;
73     
74     cout<<tot<<endl;
75     
76     return 0;
77     
78     } 

转载于:https://www.cnblogs.com/noip/archive/2012/05/30/2526763.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值