zoukankan      html  css  js  c++  java
  • HDU --3549

    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算法:

     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
    ", ++cnt, EK(1, N));
    75     }
    76     return 0;
    77 }

    Dinic算法:

     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
    ", ++cnt,flow);
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    无题
    无题
    Windows NT 和 VMS: 其余的故事 (The Rest of the Story)
    Lachesis Shield Released!
    最近几年来看到的最强的照片
    有关 Nintendo GameCube
    那些带给我欢乐的游戏
    习惯了 .#
    Rootkits
    我写的IDA插件发布了
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3585181.html
Copyright © 2011-2022 走看看