zoukankan      html  css  js  c++  java
  • Drainage Ditches(Dinic最大流)

    http://poj.org/problem?id=1273

    用Dinic求最大流的模板题,注意会有重边。

    邻接矩阵建图

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn = 510;
     7 const int INF = 0x3f3f3f3f;
     8 int flow[maxn][maxn];//残量
     9 int m,n;
    10 int dis[maxn];
    11 int bfs()//按层数“建”图,就是对每层的点用dis标记它到源点的层数
    12 {
    13     queue<int>que;
    14     memset(dis,-1,sizeof(dis));
    15     while(!que.empty())
    16         que.pop();
    17     dis[1] = 0;
    18     que.push(1);
    19 
    20     while(!que.empty())
    21     {
    22         int u = que.front();
    23         que.pop();
    24 
    25         for(int i = 1; i <= n; i++)
    26         {
    27             if(flow[u][i] > 0 && dis[i] < 0)
    28             {
    29                 dis[i] = dis[u]+1;
    30                 que.push(i);
    31             }
    32         }
    33     }
    34 
    35     if(dis[n] > 0)
    36         return 1;
    37     else return 0;
    38 }
    39 //dfs寻找路径上的最小流量
    40 int dfs(int s, int mf)
    41 {
    42     int a;
    43     if(s == n)
    44         return mf;
    45     for(int i = 1; i <= n; i++)
    46     {
    47         if(dis[i] == dis[s] + 1 && flow[s][i] > 0 && (a = dfs(i,min(mf,flow[s][i]))))
    48         {
    49             flow[s][i] -= a;
    50             flow[i][s] += a;
    51             return a;
    52         }
    53     }
    54     return 0;
    55 }
    56 
    57 int main()
    58 {
    59     while(~scanf("%d %d",&m,&n))
    60     {
    61         int u,v,w;
    62         memset(flow,0,sizeof(flow));
    63         for(int i = 0; i < m; i++)
    64         {
    65             scanf("%d %d %d",&u,&v,&w);
    66             flow[u][v] += w;
    67         }
    68         int ans = 0,res;
    69         while(bfs())//bfs寻找源点到汇点是否有路
    70         {
    71             res = dfs(1,INF);
    72             if(res > 0)
    73                 ans += res;
    74         }
    75         printf("%d
    ",ans);
    76     }
    77     return 0;
    78 
    79 }
    View Code

    邻接表建图

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<queue>
      4 #include<algorithm>
      5 using namespace std;
      6 const int maxn = 510;
      7 const int INF = 0x3f3f3f3f;
      8 int m,n,cnt;
      9 struct node
     10 {
     11     int u,v,w;
     12     int next;
     13 }edge[maxn];
     14 int p[maxn];
     15 int dis[maxn];
     16 void add(int u, int v, int w)
     17 {
     18 
     19     edge[cnt].u = u;
     20     edge[cnt].v = v;
     21     edge[cnt].w = w;
     22     edge[cnt].next = p[u];
     23     p[u] = cnt++;
     24 
     25     edge[cnt].u = v;
     26     edge[cnt].v = u;
     27     edge[cnt].w = 0;
     28     edge[cnt].next = p[v];
     29     p[v] = cnt++;
     30 }
     31 
     32 int bfs()
     33 {
     34     queue<int> que;
     35     while(!que.empty())
     36         que.pop();
     37     memset(dis,-1,sizeof(dis));
     38     dis[1] = 0;
     39     que.push(1);
     40 
     41     while(!que.empty())
     42     {
     43         int u = que.front();
     44         que.pop();
     45 
     46         for(int i = p[u]; i != -1; i = edge[i].next)
     47         {
     48             if(edge[i].w > 0 && dis[ edge[i].v ] < 0)
     49             {
     50                 dis[ edge[i].v ] = dis[u] + 1;
     51                 que.push(edge[i].v);
     52             }
     53         }
     54     }
     55     if(dis[n] > 0)
     56         return 1;
     57     else return 0;
     58 }
     59 
     60 int dfs(int s, int mf)
     61 {
     62     if(s == n)
     63         return mf;
     64     int a;
     65     int tf = 0;
     66     for(int i = p[s]; i != -1; i = edge[i].next)
     67     {
     68         int v = edge[i].v;
     69         int w = edge[i].w;
     70         if(dis[v] == dis[s] + 1 && w > 0 && (a = dfs(v,min(mf,w))))
     71         {
     72             edge[i].w -= a;
     73             edge[i^1].w += a;
     74             return a;
     75         }
     76     }
     77     if(!tf)//若找不到小流,从这个点到不了汇点,把这个点从分层图删去
     78         dis[s] = -1;
     79     return tf;
     80 }
     81 
     82 int main()
     83 {
     84     while(~scanf("%d %d",&m,&n))
     85     {
     86         int u,v,w;
     87         cnt = 0;
     88         memset(p,-1,sizeof(p));
     89         for(int i = 0; i < m; i++)
     90         {
     91             scanf("%d %d %d",&u,&v,&w);
     92             add(u,v,w);
     93         }
     94         int ans = 0;
     95         int res;
     96         while(bfs())
     97         {
     98             res = dfs(1,INF);
     99             if(res > 0)
    100                 ans += res;
    101         }
    102         printf("%d
    ",ans);
    103     }
    104 
    105     return 0;
    106 }
    View Code
  • 相关阅读:
    c# 文件上传
    iOSswift基础篇1
    copyWithZone 的使用方法
    客户端登陆接收大量数据导致数据丢失问题解决方法
    设计模式观察者模式(KVO)
    SQLite 之 C#版 System.Data.SQLite 使用
    设计模式MVC(C++版)
    JS 创建自定义对象的方法
    手机号、邮箱、身份证号 格式 验证
    在.cs文件中添加客户端方法
  • 原文地址:https://www.cnblogs.com/LK1994/p/3462803.html
Copyright © 2011-2022 走看看