zoukankan      html  css  js  c++  java
  • 网络流——poj1273(入门)

    题目链接:排水沟

    题意:现有n个排水沟和m个点(其中1是源点,m是汇点),给定n个排水沟所连接的点,求从源点到汇点的最大流量。

    【EK解法】

     1 #include <algorithm>  
     2 #include <queue>  
     3 #include <string.h>  
     4 using namespace std;  
     5 int const MAX = 1005;  
     6 int const inf = 0x3f3f3f3f;  
     7 int c[MAX][MAX];//c[u][v]保存容量  
     8 int f[MAX][MAX];//f[u][v]保存当前流量  
     9 int a[MAX];// a数组在每趟bfs中找到最小路径中最小残余流量的,a数组使个递推数组,a[v]的意思是从源点s到点v的最小残余流量  
    10 int p[MAX];//保存前一个点  
    11 int n, m;  
    12 int bfs(int s, int t)  
    13 {  
    14     queue<int> q;  
    15     int flow = 0;  
    16     while(!q.empty())   q.pop();  
    17     memset(f, 0, sizeof(f));  
    18     while(1){  
    19         memset(a, 0, sizeof(a));  
    20         a[s] = inf;//将起始点的最小残余量设为最大  
    21         q.push(s);  
    22         while(!q.empty()){//bfs找到一条最短路,这里的边不代表距离,可以看作每两个点都是单位距离的  
    23             int u;  
    24             u = q.front();  
    25             q.pop();  
    26             for(int v = 1; v <= m; v++){//枚举所有点v <u,v>  
    27                 if(!a[v] && c[u][v] > f[u][v]){//a[]可以代替vis[],来判断这个点是否已经遍历过,后面那个条件更是起了关键作用,很巧妙  
    28                     p[v] = u;  
    29                     q.push(v);  
    30                     a[v] = min(a[u], c[u][v] - f[u][v]);//递推  
    31                 }  
    32             }  
    33         }  
    34         if(!a[t])   break;//直到最小残余流量为0时,退出  
    35         for(int u = t; u != s; u = p[u]){  
    36             f[p[u]][u] += a[t];  
    37             f[u][p[u]] -= a[t];  
    38         }  
    39         flow += a[t];  
    40     }  
    41     return flow;  
    42 }  
    43   
    44 int main()  
    45 {  
    46     while(~scanf("%d %d", &n, &m)){  
    47         memset(c, 0, sizeof(c));  
    48         memset(p, 0, sizeof(p));  
    49         for(int i = 1; i <= n; i++){  
    50             int u, v, w;  
    51             scanf("%d %d %d", &u, &v, &w);  
    52             c[u][v] += w;  
    53         }  
    54         printf("%d
    ", bfs(1, m));  
    55     }  
    56     return 0;  
    57 }
    EK解法

    【Dinic解法】

     1 #include <cstdio>
     2 #include <string.h>
     3 #include <queue>
     4 using namespace std;
     5 int const inf = 0x3f3f3f3f;
     6 int const MAX = 205;
     7 int n, m;
     8 int c[MAX][MAX], dep[MAX];//dep[MAX]代表当前层数
     9 
    10 int bfs(int s, int t)//重新建图,按层次建图
    11 {
    12     queue<int> q;
    13     while(!q.empty())
    14         q.pop();
    15     memset(dep, -1, sizeof(dep));
    16     dep[s] = 0;
    17     q.push(s);
    18     while(!q.empty()){
    19         int u = q.front();
    20         q.pop();
    21         for(int v = 1; v <= m; v++){
    22             if(c[u][v] > 0 && dep[v] == -1){//如果可以到达且还没有访问,可以到达的条件是剩余容量大于0,没有访问的条件是当前层数还未知
    23                 dep[v] = dep[u] + 1;
    24                 q.push(v);
    25             }
    26         }
    27     }
    28     return dep[t] != -1;
    29 }
    30 
    31 int dfs(int u, int mi, int t)//查找路径上的最小流量
    32 {
    33     if(u == t)
    34         return mi;
    35     int tmp;
    36     for(int v = 1; v <= m; v++){
    37         if(c[u][v] > 0 && dep[v] == dep[u] + 1  && (tmp = dfs(v, min(mi, c[u][v]), t))){
    38             c[u][v] -= tmp;
    39             c[v][u] += tmp;
    40             return tmp;
    41         }
    42     }
    43     return 0;
    44 }
    45 
    46 int dinic()
    47 {
    48     int ans = 0, tmp;
    49     while(bfs(1, m)){
    50         while(1){
    51             tmp = dfs(1, inf, m);
    52             if(tmp == 0)
    53                 break;
    54             ans += tmp;
    55         }
    56     }
    57     return ans;
    58 }
    59 
    60 int main()
    61 {
    62     while(~scanf("%d %d", &n, &m)){
    63         memset(c, 0, sizeof(c));
    64         int u, v, w;
    65         while(n--){
    66             scanf("%d %d %d", &u, &v, &w);
    67             c[u][v] += w;
    68         }
    69         printf("%d
    ", dinic());
    70     }
    71     return 0;
    72 }
    Dinic解法
  • 相关阅读:
    《哈佛商业评论》2018正刊12期与增刊25期的点评
    《财经》2018年共30+1期的点评与摘抄
    4星|《人人都在说谎》:社会科学方面有趣的数据分析方法与结论
    3星|侯世达《我是个怪圈》:关于人类意识的各种哲学思辨
    虚拟机 SUSE Linux Enterprise Server 12 SP2 64
    虚拟机 CentOS7 64
    虚拟机 ubuntu 16.04
    虚拟机 windows xp sp3 原版
    C#实现控制Windows系统关机、重启和注销的方法
    日期时间设置 "2018-05-04T16:36:23.6341371+08:00" 格式
  • 原文地址:https://www.cnblogs.com/xzxl/p/7349559.html
Copyright © 2011-2022 走看看