1 /******************************************************************
 2  题目:     Drainage Ditches(POJ 1273)
 3  链接:     http://poj.org/problem?id=1273
 4  题意:     现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条
 5             水渠,给出这n条水渠所连接的池塘和所能流过的水量,求水
 6             渠中所能流过的水的最大容量.水流是单向的。
 7  算法:     最大流之增广路(入门)
 8  算法思路: 不断用BFS找通路,没每找一条路,记录这条路的最小流,再
 9             给这条路上的所有流量减去这个最小值。
10 *********************************************************************/
11 #include<cstdio>
12 #include<iostream>
13 #include<cstring>
14 #include<algorithm>
15 #include<queue>
16 using namespace std;
17 
18 const int mx=222;
19 int cap[mx][mx];        ///两个端点的流量。
20 int flow[mx][mx];       ///两个端点已用的流量。
21 int a[mx],father[mx];
22 int m,n;
23 
24 int bfs()
25 {
26     queue<int>q;
27     int ans=0;
28     father[1]=-1;
29     while (1)
30     {
31         memset(a,0,sizeof(a));
32         a[1]=1000000000;
33         q.push(1);
34         ///找增广路
35         while (!q.empty())
36         {
37             int u=q.front();
38             q.pop();
39             for (int v=2;v<=n;v++)
40             {
41                 if (!a[v]&&cap[u][v]>flow[u][v])
42                 {
43                     father[v]=u;
44                     q.push(v);
45                     a[v]=min(a[u],cap[u][v]-flow[u][v]);
46                 }
47             }
48         }
49         if (a[n]==0) return ans;
50         for (int u=n;father[u]!=-1;u=father[u])
51         {
52             flow[u][father[u]]-=a[n];            ///更新反向流量        
53             flow[father[u]][u]+=a[n];           ///更新正向流量
54         }
55         ans+=a[n];                           
56     }
57 }
58 
59 int main()
60 {
61     while (~scanf("%d%d",&m,&n))
62     {
63         memset(cap,0,sizeof(cap));
64         memset(flow,0,sizeof(flow));
65         int u,v,w;
66         while (m--)
67         {
68             scanf("%d%d%d",&u,&v,&w);
69             cap[u][v]+=w;
70         }
71         int ans=bfs();
72         printf("%d\n",ans);
73     }
74 }

 

 1 /*********************************************************
 2 题目:        Drainage Ditches(poj 1273)
 3 算法:      最大流之dinic(入门)
 4 算法思想:  dinic的主要思想是层次图和阻塞流,只保留每个节点
 5              出发到下一个层次的弧,得到的图就叫层次图。阻塞
 6             流就是不考虑反向弧时的极大流。先用bfs分层,再计
 7             算阻塞流,不断从复这两步,直到找不到阻塞流结束。
 8 ************************************************************/
 9 #include<cstdio>
10 #include<cstring>
11 #include<algorithm>
12 #include<iostream>
13 #include<queue>
14 using namespace std;
15 
16 const int mx=222;
17 int map[mx][mx];
18 int d[mx];
19 int m,n;
20 
21 ///分层
22 int bfs()
23 {
24     queue<int>q;
25     memset(d,0,sizeof(d));
26     q.push(1);
27     while (!q.empty())
28     {
29         int u=q.front();
30         q.pop();
31         for (int v=2;v<=n;v++)
32         {
33             if (!d[v]&&map[u][v]>0)
34             {
35                 d[v]=d[u]+1;
36                 q.push(v);
37             }
38         }
39     }
40     return d[n];
41 }
42 
43 ///计算阻塞流
44 int dfs(int u,int w)
45 {
46     if (u==n||w==0) return w;
47     int ans=0;
48     int temp;
49     for (int v=2;v<=n;v++)
50     {
51         if (map[u][v]>0&&d[u]==d[v]-1)
52         {
53             int temp=dfs(v,min(w,map[u][v]));
54             ans+=temp;
55             map[u][v]-=temp;    ///正向更新
56             map[v][u]+=temp;    ///方向更新
57             w-=temp;            ///从v流出的流量不能大于w。
58         }
59     }
60     return ans;
61 }
62 
63 ///dinic算法
64 int dinic()
65 {
66     int ans=0;
67     while (bfs())
68     ans+=dfs(1,1000000000);
69     return ans;
70 }
71 
72 int main()
73 {
74     while (~scanf("%d%d",&m,&n))
75     {
76         memset(map,0,sizeof(map));
77         int u,v,w;
78         while (m--)
79         {
80             scanf("%d%d%d",&u,&v,&w);
81             map[u][v]+=w;
82         }
83         printf("%d\n",dinic());
84     }
85 }

 

posted on 2016-06-03 20:17  pb2016  阅读(191)  评论(0编辑  收藏  举报