首页 > 其他 > 详细

HDU --3549

时间:2014-03-07 07:41:22      阅读:417      评论:0      收藏:0      [点我收藏+]

Flow Problem

Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 6336    Accepted Submission(s): 2943


Problem Description
Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.
 

 

Input
The first line of input contains an integer T, denoting the number of test cases.
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)
 

 

Output
For each test cases, you should output the maximum flow from source 1 to sink N.
 

 

Sample Input
2
3 2
1 2 1
2 3 1
3 3
1 2 1
2 3 1
1 3 1
 

 

Sample Output
Case 1: 1
Case 2: 2

 思路:最大网络流模板题,都是FF方法,根据增广路求增广流量,算法的关键在于如何快速求增广路。Edmond-Karp是根据BFS求增广路,Dinic则先通过BFS将残余网络进行层次划分,即将距离源点S边数为x的点标记为level[i] = x,如果level[j] = level[i] + 1且res[i][j] > 0,那么<i,j>称为可行边。再对残余网络进行一遍DFS,搜索的时候就是根据level[i] = level[s]+1且res[s][i] > 0来向下递归的,所以相对于EK算法可以减少无谓的搜索,这样只要汇点T在层次图中,总会找到它。

Edmod-Karp算法:

bubuko.com,布布扣
 1 #include<iostream>
 2 #include<queue>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 int res[20][20], vis[20], pre[20];
 7 queue<int>q;
 8 int N, M;
 9 bool bds(int s, int t)
10 {
11     memset(vis, 0, sizeof(vis));
12     memset(pre, -1, sizeof(pre));
13     while(!q.empty())
14         q.pop();
15     q.push(s);
16     vis[s] = 1;
17     while(!q.empty())
18     {
19         int p = q.front();
20         q.pop();
21         for(int i = 1;i <= N;i ++)
22         {
23             if(!vis[i] && res[p][i] > 0)
24             {
25                 vis[i] = 1;
26                 pre[i] = p;
27                 q.push(i);
28                 if(i == t)
29                     return true;
30             }
31         }
32     }
33     return false;
34 }
35 
36 int EK(int s, int t)
37 {
38     int flow = 0, d, i, u;
39     while(bds(s, t))
40     {
41         d = 1 << 30;
42         u = t;
43         while(pre[u] != -1)
44         {
45             d = min(d, res[pre[u]][u]);
46             u = pre[u];
47         }
48         u = t;
49         while(pre[u] != -1)
50         {
51             res[pre[u]][u] -= d;
52             res[u][pre[u]] += d;
53             u = pre[u];
54         }
55         flow += d;
56     }
57     return flow;
58 }
59 
60 int main(int argc, char const *argv[]) 
61 {
62     int T, u, v, w, cnt = 0;
63     //freopen("in.c", "r", stdin);
64     scanf("%d", &T);
65     while(T--)
66     {
67         memset(res, 0, sizeof(res));
68         scanf("%d%d", &N, &M);
69         for(int i = 0;i < M;i ++)
70         {
71             scanf("%d%d%d", &u, &v, &w);
72             res[u][v] += w;
73         }
74         printf("Case %d: %d\n", ++cnt, EK(1, N));
75     }
76     return 0;
77 }
bubuko.com,布布扣

Dinic算法:

bubuko.com,布布扣
 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 int res[20][20], level[20], N, M, flow;
 7 queue<int>q;
 8 bool bfs(int s)
 9 {
10     while(!q.empty())
11         q.pop();
12     memset(level, -1, sizeof(level));
13     level[s] = 0;
14     q.push(s);
15     while(!q.empty())
16     {
17         int p = q.front();
18         q.pop();
19         for(int i = 1;i <= N;i ++)
20         {
21             if(level[i] == -1 && res[p][i] > 0)
22             {
23                 level[i] = level[p] + 1;
24                 q.push(i);
25             }
26         }
27     }
28     if(level[N] >= 0)
29         return true;
30     return false;
31 }
32 
33 int dinic(int s, int sum)
34 {
35     if(s == N)
36         return sum;
37     int os = sum;
38     for(int i = 1;i <= N;i ++)
39     {
40         if(level[i] == level[s] + 1 && res[s][i] > 0)
41         {
42             int temp = dinic(i, min(sum, res[s][i]));
43             res[s][i] -= temp;
44             res[i][s] += temp;
45             sum -= temp;
46         }
47     }
48     return os - sum;
49 }
50 
51 int main(int argc, char const *argv[]) 
52 {
53     int T, u, v, w,cnt = 0;
54    // freopen("in.c", "r", stdin);
55     scanf("%d", &T);
56     while(T--)
57     {
58         flow = 0;
59         memset(res, 0, sizeof(res));
60         scanf("%d%d", &N, &M);
61         for(int i = 0; i < M;i ++)
62         {
63             scanf("%d%d%d", &u, &v, &w);
64             res[u][v] += w;
65         }
66         while(bfs(1))
67             flow += dinic(1,1 << 30);
68         printf("Case %d: %d\n", ++cnt,flow);
69     }
70     return 0;
71 }
bubuko.com,布布扣

 

HDU --3549,布布扣,bubuko.com

HDU --3549

原文:http://www.cnblogs.com/anhuizhiye/p/3585181.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!