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 }
  • 相关阅读:
    动态更新活动条件
    使用本地服务异步执行自定义活动业务逻辑
    隐藏自定义复合活动的内部实现
    如何开发一个基本的复合活动
    HTML5性能之争 —— 单线程:缺点还是特点?
    CDNJS —— Web 上最快的 JavaScript 资源库
    Comfusion 4.1 发布,桌面 Linux 发行
    FreeBSD 9.1 正式版已经可以下载
    Squid Analyzer 5.0 发布,Squid日志统计
    MemSQL 1.8 发布,号称最快的关系数据库
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3585181.html
Copyright © 2011-2022 走看看