• 网络流最经典的入门题 各种网络流算法都能AC。 poj 1273 Drainage Ditches


                                  Drainage Ditches

    题目抽象:给你m条边u,v,c。   n个定点,源点1,汇点n.求最大流。  最好的入门题,各种算法都可以拿来练习

    (1):  一般增广路算法  ford()

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <string>
      7 #include <vector>
      8 #include <set>
      9 #include <map>
     10 #include <stack>
     11 #include <queue>
     12 #include <sstream>
     13 #include <iomanip>
     14 using namespace std;
     15 typedef long long LL;
     16 const int INF = 0x4fffffff;
     17 const double EXP = 1e-5;
     18 const int MS = 10005;
     19 const int SIZE = 10005;
     20 
     21 struct edge
     22 {
     23     int c, f;
     24 }edges[MS][MS];
     25 
     26 int n, m;
     27 
     28 int flag[MS];
     29 int pre[MS];
     30 int alpha[MS];
     31 
     32 int que[SIZE];
     33 
     34 int u;
     35 int qs, qe;
     36 int i, j;
     37 
     38 void ford()
     39 {
     40     while (1)
     41     {
     42         //  label method
     43         memset(flag, 0xff, sizeof(flag));
     44         memset(pre, 0xff, sizeof(pre));
     45         memset(alpha, 0xff, sizeof(alpha));
     46         flag[1] = 0;
     47         pre[1] = 0;
     48         alpha[1] = INF;
     49         qs = qe = 0;
     50         que[qe++] = 1;
     51 
     52         while (qs < qe&&flag[n ] == -1)
     53         {
     54             u = que[qs++];
     55             for (int i = 1; i <= n; i++)
     56             {
     57                 if (flag[i] == -1)
     58                 {
     59                     if (edges[u][i].c >0&&edges[u][i].f < edges[u][i].c)
     60                     {
     61                         flag[i] = 0; pre[i] = u;
     62                         alpha[i] = min(alpha[u], edges[u][i].c - edges[u][i].f);
     63                         que[qe++] = i;
     64                     }
     65                     else if (edges[i][u].c>0&&edges[i][u].f>0)
     66                     {
     67                         flag[i] = 0; pre[i] = -u;
     68                         alpha[i] = min(alpha[u], edges[i][u].f);
     69                         que[qe++] = i;
     70                     }
     71                 }
     72             }
     73             flag[u] = 1;
     74         }    //  END OF WHILE
     75         if (flag[n ] == -1 || alpha[n ] == 0)
     76             break;       //  END OF WHILE
     77 
     78         int k1 = n , k2 = abs(pre[k1]);
     79         int a = alpha[n ];
     80         while (1)
     81         {
     82             if (edges[k2][k1].c>0)         //用f是否==INF来判断正向
     83                 edges[k2][k1].f += a;
     84             else
     85                 edges[k1][k2].f -= a;
     86             if (k2 == 1)
     87                 break;
     88             k1 = k2;
     89             k2 = abs(pre[k1]);
     90         }     //  END OF WHILE
     91     }  //  END OF WHILE
     92 
     93     int max_flow = 0;
     94     for (int i = 1; i <=n; i++)
     95     {
     96         for (int j = 1; j <=n; j++)
     97         {
     98             if (i == 1 && edges[i][j].f >0)
     99                 max_flow += edges[i][j].f;
    100           //  if (edges[i][j].f > 0)
    101            //     printf("%d-->%d: %d
    ", i, j, edges[i][j].f);
    102         }
    103     }
    104     printf("%d
    ", max_flow);
    105 }
    106 
    107 int main()
    108 {
    109     int u, v, c, f;
    110     while(scanf("%d%d",&m,&n)!=EOF)
    111     {
    112           for (int i = 0; i <= n; i++)
    113             for (int j = 0; j <= n; j++)
    114                  // edges[i][j].c = edges[i][j].f = INF;
    115                  edges[i][j].c=edges[i][j].f=0;
    116           for (int i = 0; i < m; i++)
    117           {
    118               //scanf("%d%d%d%d", &u, &v, &c, &f);
    119               scanf("%d%d%d",&u,&v,&c);         //   这里是零流
    120               edges[u][v].c +=c;                           //  可能有重边
    121              // edges[u][v].f = f;
    122           }
    123           ford();
    124     }
    125     return 0;
    126 }

     (2):  dinic()

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <string>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <list>
    13 #include <iomanip>
    14 #include <cstdlib>
    15 #include <sstream>
    16 using namespace std;
    17 typedef long long LL;
    18 const int INF=0x5fffffff;
    19 const double EXP=1e-6;
    20 const int MS=1005;
    21 
    22 int edges[MS][MS];
    23 int level[MS];
    24 int que[MS],qs,qe;
    25 int n,m,ans;
    26 
    27 int BFS()   // BFS求level
    28 {
    29     memset(level,0xff,sizeof(level));
    30     level[1]=0;
    31     qs=qe=0;
    32     que[qe++]=1;
    33     while(qs<qe)
    34     {
    35         int u=que[qs++];
    36         for(int v=1;v<=n;v++)
    37         {
    38             if(level[v]<0&&edges[u][v]>0)
    39             {
    40                 level[v]=level[u]+1;
    41                 que[qe++]=v;
    42             }
    43         }
    44     }
    45     if(level[n]>0)    //  汇点在残留网络中,存在增广路
    46         return 1;
    47     else
    48         return 0;
    49 }
    50 
    51 int DFS(int u,int minv)
    52 {
    53     if(u==n)
    54         return minv;
    55     int t;
    56     for(int v=1;v<=n;v++)
    57         if(edges[u][v]>0&&level[v]==level[u]+1&&(t=DFS(v,min(minv,edges[u][v]))))
    58         {
    59             edges[u][v]-=t;
    60             edges[v][u]+=t;
    61             return t;
    62         }
    63     return 0;
    64 }
    65 
    66 int main()
    67 {
    68     int u,v,c;
    69     while(scanf("%d%d",&m,&n)!=EOF)
    70     {
    71         memset(edges,0,sizeof(edges));
    72         for(int i=1;i<=m;i++)
    73         {
    74             scanf("%d%d%d",&u,&v,&c);
    75             edges[u][v]+=c;
    76         }
    77         ans=0;
    78         int t;
    79         //  DINIC()
    80         while(BFS())  //还存在增广路
    81         {
    82             while(t=DFS(1,INF))   //DFS找出残留网络中的所有增广路
    83             {
    84                 ans+=t;
    85             }
    86         }
    87         printf("%d
    ",ans);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    Mysql 密码过期
    【Linux】 设置Linux的系统时间
    【Ubantu】ubantu 安装 .net core 3.0 的环境
    【Ubantu】Ubantu的常用命令
    【SQL】一个简单的查询所有层级(直到顶层)的sql语句
    【C++】C++中的异常解析
    【C++】C++中的类模板
    【Eclipse】Eclipse如何导出java项目为jar包
    【Kali】kali linux的安装和配置
    【Python】解析Python中的线程与进程
  • 原文地址:https://www.cnblogs.com/767355675hutaishi/p/4423447.html
Copyright © 2020-2023  润新知