描述
在农夫约翰的农场上,每逢下雨,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 }