• POJ_1273 Drainage Ditches 【网络流】


    一、题面

      Drainage Ditches

    二、分析

      网络流的裸题。

      1 Edmonds-Karp算法

        求解网络流其实就是一个不断找增广路,然后每次找到一条增广路后更新残余网络的一个过程。

        EK算法主要就是用bfs去找增广路,然后不断更新残余网络得到最终答案。

      2 Dinic算法

        对于Ford-Fulkerson和Edmonds-Karp算法,求解网络流都是一次次用DFS或者BFS,这其实是很费时的,Dinic相当于就是一次BFS然后DFS求解出多条增广路。

      3 ISAP

    三、AC代码

     1 //Edmonds-Karp
     2 #include <cstdio>
     3 #include <iostream>
     4 #include <vector>
     5 #include <queue>
     6 #include <cstring>
     7 using namespace std;
     8 #define ll long long
     9 const int maxn = 2e2 + 13;
    10 const int INF = 1e8 + 1;
    11 int N, M;
    12 int Flow[maxn]; //找到的最小的容量
    13 int Pre[maxn];  //记录父节点
    14 struct edge
    15 {
    16     //终点、容量、反边
    17     int to, cap, rev;
    18 };
    19 int G[maxn][maxn];
    20 void add_edge(int from, int to, int cap)
    21 {
    22     G[from][to] += cap;
    23 }
    24 
    25 int BFS(int s, int t)
    26 {
    27     memset(Pre, -1, sizeof(Pre));
    28     queue<int> Q;
    29     Q.push(s);
    30     Pre[s] = -1;
    31     Flow[s] = INF;
    32     while(!Q.empty())
    33     {
    34         int q = Q.front();
    35         if(q == t)
    36             break;
    37         Q.pop();
    38         for(int i = 1; i <= M; i++)
    39         {
    40             if(i != s && G[q][i] > 0 && Pre[i] == -1)
    41             {
    42                 Pre[i] = q;
    43                 Flow[i] = min(Flow[q], G[q][i]);
    44                 Q.push(i);
    45             }
    46         }
    47     }
    48     if(Pre[t] == -1)
    49         return 0;
    50     else
    51         return Flow[t];
    52 }
    53 
    54 ll EK(int s, int t)
    55 {
    56     ll ans = 0;
    57     int f = BFS(s, t);
    58     while(f)
    59     {
    60         ans += f;
    61         int p = t;
    62         while(Pre[p] != -1)
    63         {
    64             G[Pre[p]][p] -= f;
    65             G[p][Pre[p]] += f;
    66             p = Pre[p];
    67         }
    68         f = BFS(s, t);
    69     }
    70     return ans;
    71 }
    72 
    73 int main()
    74 {
    75     freopen("input.txt", "r", stdin);
    76     while(scanf("%d%d", &N, &M) != EOF)
    77     {
    78         memset(G, 0, sizeof(G));
    79         int from, to, cap;
    80         for(int i = 0; i < N; i++)
    81         {
    82             scanf("%d%d%d", &from, &to, &cap);
    83             add_edge(from, to, cap);
    84         }
    85         printf("%I64d
    ", EK(1, M));
    86     }
    87     return 0;
    88 }
      1 //Dinic
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 
      9 using namespace std;
     10 #define ll long long
     11 #define Min(a,b) ((a)>(b)?(b):(a))
     12 #define Max(a,b) ((a)>(b)?(a):(b))
     13 const int INF = 1e9;
     14 const int maxn = 5e2 + 13;
     15 struct edge
     16 {
     17     int to, cap, rev;
     18 };
     19 vector<edge> G[maxn];
     20 int N, M;
     21 int level[maxn], iter[maxn];
     22 //iter数组的作用就是记录DFS时该结点已经访问到的邻接点的位置
     23 void add_edge(int from, int to, int cap)
     24 {
     25     G[from].push_back( (edge){to, cap, G[to].size()});
     26     G[to].push_back( (edge){from, 0, G[from].size() - 1});
     27 }
     28 
     29 void BFS(int s)
     30 {
     31     memset(level, -1, sizeof(level));
     32     queue<int> que;
     33     level[s] = 0;
     34     que.push(s);
     35     while(!que.empty())
     36     {
     37         int v = que.front();
     38         que.pop();
     39         for(int i = 0; i < G[v].size(); i++)
     40         {
     41             edge &e = G[v][i];
     42             if(e.cap > 0 && level[e.to] < 0)
     43             {
     44                 level[e.to] = level[v] + 1;
     45                 que.push(e.to);
     46             }
     47         }
     48     }
     49 }
     50 
     51 int DFS(int s, int t, int f)
     52 {
     53     if(s == t)
     54         return f;
     55     for(int &i = iter[s]; i < G[s].size(); i++)
     56     {
     57         edge &e = G[s][i];
     58         if(e.cap > 0 && level[s] < level[e.to])
     59         {
     60             int d = DFS(e.to, t, Min(f, e.cap));
     61             if(d > 0)
     62             {
     63                 e.cap -= d;
     64                 G[e.to][e.rev].cap += d;
     65                 return d;
     66             }
     67         }
     68     }
     69     return 0;
     70 }
     71 
     72 int Dinic(int s, int t)
     73 {
     74     int flow = 0;
     75     while(1)
     76     {
     77         BFS(s);
     78         if(level[t] < 0)
     79             return flow;
     80         memset(iter, 0, sizeof(iter));
     81         int f = DFS(s, t, INF);
     82         while(f > 0)
     83         {
     84             flow += f;
     85             f = DFS(s, t, INF);
     86         }
     87     }
     88 }
     89 
     90 int main()
     91 {
     92     //freopen("input.txt", "r", stdin);
     93     int from, to, cap;
     94     while(~scanf("%d%d", &N, &M))
     95     {
     96         for(int i = 0; i < N; i++)
     97         {
     98             scanf("%d%d%d", &from, &to, &cap);
     99             add_edge(from, to, cap);
    100         }
    101         printf("%d
    ", Dinic(1, M));
    102         for(int i = 1; i < M; i++)
    103         {
    104             G[i].clear();
    105         }
    106     }
    107     return 0;
    108 }
      1 //ISAP
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 
      9 using namespace std;
     10 #define ll long long
     11 #define Min(a,b) ((a)>(b)?(b):(a))
     12 #define Max(a,b) ((a)>(b)?(a):(b))
     13 const int INF = 1e9;
     14 const int maxn = 2e2 + 13;
     15 struct edge{
     16     int v, w, nxt;
     17 } e[maxn<<1];
     18 int h[maxn], tot, n, m, gap[maxn], last[maxn], d[maxn],que[maxn], ql, qr;
     19 vector<int> inv[maxn];
     20 
     21 int read() {
     22     int x=0,f=1;
     23     char c=getchar();
     24     for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
     25     for (;isdigit(c);c=getchar()) x=x*10+c-'0';
     26     return x*f;
     27 }
     28 
     29 void add(int u, int v, int w)
     30 {
     31     e[++tot] = (edge){v, w, h[u]};
     32     h[u] = tot;
     33     e[++tot] = (edge){u, 0, h[v]};
     34     h[v] = tot;
     35 }
     36 
     37 void init(int s, int t)
     38 {
     39     memset(gap, 0, sizeof(gap));
     40     memset(d, 0, sizeof(d));
     41     ++gap[d[t] = 1];
     42     for(int i = 1; i <= n; i++)
     43         last[i] = h[i];
     44     que[ql = qr = 1] =  t;
     45     while(ql <= qr)
     46     {
     47         int x = que[ql++];
     48         for(int i = h[x], v = e[i].v;i; i = e[i].nxt, v = e[i].v)
     49         {
     50             if(!d[v])
     51             {
     52                 ++gap[d[v] = d[x] + 1];
     53                 que[++qr] = v;
     54             }
     55         }
     56     }
     57 }
     58 
     59 int aug(int x, int s, int t, int mi)
     60 {
     61     if(x == t)
     62         return mi;
     63     int flow = 0;
     64     for(int &i = last[x], v = e[i].v;i;i = e[i].nxt, v = e[i].v)
     65     {
     66         if(d[x] == d[v] + 1)
     67         {
     68             int tmp = aug(v, s, t, min(mi, e[i].w));
     69             flow += tmp;
     70             mi -= tmp;
     71             e[i].w -= tmp;
     72             e[i^1].w += tmp;
     73             if(!mi)
     74                 return flow;
     75         }
     76     }
     77     if(!(--gap[d[x]])) 
     78         d[s] = n + 1;
     79     ++gap[++d[x]];
     80     last[x] = h[x];
     81     return flow;
     82 }
     83 
     84 int maxflow(int s, int t)
     85 {
     86     init(s, t);
     87     int ret = aug(s, s, t, INF);
     88     while(d[s] <= n)
     89         ret += aug(s, s, t, INF);
     90     return ret;
     91 }
     92 
     93 int main()
     94 {
     95     freopen("input.txt", "r", stdin);
     96     while(~scanf("%d%d", &m, &n))
     97     {
     98         tot = 1;
     99         memset(h, 0, sizeof(h));
    100         for(int i = 1; i <= n; i++)
    101             inv[i].clear();
    102         for(int i = 1; i <= m; i++)
    103         {
    104             int u = read();
    105             int v = read();
    106             int w = read();
    107             add(u, v, w);
    108             if(w)
    109                 inv[v].push_back(u);
    110         }
    111         int ans = maxflow(1, n);
    112         printf("%d
    ", ans);
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    学习bn算法
    记录pytorch的几个问题
    Python: 你不知道的 super
    cmd里面怎么复制粘贴
    tensorflow的transpose
    应该做一个软件,直接把视频里面的英语,转换成字幕,然后翻译
    继续修改,爬虫贴吧,上次的每次只取一个图片.
    Deleting elements
    Map, filter and reduce
    List methods
  • 原文地址:https://www.cnblogs.com/dybala21/p/11318456.html
Copyright © 2020-2023  润新知