• 网络流模板 NetworkFlow


    身边的小伙伴们都在愉快地刷网络流,我也来写一发模板好了。

    Network Flow - Maximum Flow

    Time Limit : 1 sec, Memory Limit : 65536 KB 
    Japanese version is here
      1 #include <bits/stdc++.h>
      2 
      3 #define fread_siz 1024
      4 
      5 inline int get_c(void)
      6 {
      7     static char buf[fread_siz];
      8     static char *head = buf + fread_siz;
      9     static char *tail = buf + fread_siz;
     10 
     11     if (head == tail)
     12         fread(head = buf, 1, fread_siz, stdin);
     13 
     14     return *head++;
     15 }
     16 
     17 inline int get_i(void)
     18 {
     19     register int ret = 0;
     20     register int neg = false;
     21     register int bit = get_c();
     22 
     23     for (; bit < 48; bit = get_c())
     24         if (bit == '-')neg ^= true;
     25 
     26     for (; bit > 47; bit = get_c())
     27         ret = ret * 10 + bit - 48;
     28 
     29     return neg ? -ret : ret;
     30 }
     31 
     32 template <class T>
     33 inline T min(T a, T b)
     34 {
     35     return a < b ? a : b;
     36 }
     37 
     38 const int inf = 2e9;
     39 const int maxn = 20005;
     40 
     41 int n, m;
     42 int s, t;
     43 
     44 int edges;
     45 int hd[maxn];
     46 int to[maxn];
     47 int nt[maxn];
     48 int fl[maxn];
     49 
     50 inline void add(int u, int v, int f)
     51 {
     52     nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; hd[u] = edges++;
     53     nt[edges] = hd[v]; to[edges] = u; fl[edges] = 0; hd[v] = edges++;
     54 }
     55 
     56 int dep[maxn];
     57 
     58 inline bool bfs(void)
     59 {
     60     static int que[maxn];
     61     static int head, tail;
     62     
     63     memset(dep, 0, sizeof(dep));
     64     head = 0, tail = 0;
     65     que[tail++] = s;
     66     dep[s] = 1;
     67     
     68     while (head != tail)
     69     {
     70         int u = que[head++], v;
     71         for (int i = hd[u]; ~i; i = nt[i])
     72             if (!dep[v = to[i]] && fl[i])
     73                 dep[v] = dep[u] + 1, que[tail++] = v;
     74     }
     75     
     76     return dep[t];
     77 }
     78 
     79 inline int dfs(int u, int f)
     80 {
     81     if (u == t || !f)
     82         return f;
     83     
     84     int used = 0, flow, v;
     85     
     86     for (int i = hd[u]; ~i; i = nt[i])
     87         if (dep[v = to[i]] == dep[u] + 1 && fl[i])
     88         {
     89             flow = dfs(v, min(f - used, fl[i]));
     90             
     91             used += flow;
     92             fl[i] -= flow;
     93             fl[i^1] += flow;
     94             
     95             if (used == f)
     96                 return f;
     97         }
     98         
     99     if (!used)
    100         dep[u] = 0;
    101         
    102     return used;
    103 }
    104 
    105 inline int dinic(void)
    106 {
    107     int maxFlow = 0, newFlow;
    108     
    109     while (bfs())
    110         while (newFlow = dfs(s, inf))
    111             maxFlow += newFlow;
    112             
    113     return maxFlow;
    114 }
    115 
    116 signed main(void)
    117 {
    118     n = get_i();
    119     m = get_i();
    120     
    121     memset(hd, -1, sizeof(hd));
    122     
    123     for (int i = 1; i <= m; ++i)
    124     {
    125         int u = get_i();
    126         int v = get_i();
    127         int f = get_i();
    128         add(u, v, f);
    129     }
    130     
    131     s = 0, t = n - 1;
    132     
    133     printf("%d
    ", dinic());
    134 }

    Network Flow - Minimum Cost Flow

    Time Limit : 1 sec, Memory Limit : 65536 KB

    最小費用流

    各辺にコストが設定されたフローネットワークにおいて、始点 ss から終点 tt まで流用 FF のフローを流すための最小コストを求めてください。

    フローネットワークの各辺 ee には容量 c(e)c(e) 及びコスト d(e)d(e) が設定されています。各辺 ee には容量 c(e)c(e)を超えない流量 f(e)f(e) のフローを流すことができます。始点 ss から終点 tt へ流量 FF のフローを流したときの、e(f(e)×d(e))∑e(f(e)×d(e)) の最小値を求めてください。

    入力

    フローネットワーク G(V,E)G(V,E) が以下の形式で与えられる。

    |V||E|F|V||E|F
    u0v0c0d0u0v0c0d0
    u1v1c1d1u1v1c1d1
    :
    u|E|1v|E|1c|E|1d|E|1u|E|1v|E|−1c|E|−1d|E|−1

    |V||V|, |E||E|, FF はそれぞれフローネットワーク GG の頂点の数、辺の数、流したい流量を示す。 GG の頂点にはそれぞれ 0,1,...,|V|10,1,...,|V|−1 の番号が付けられており、始点を 0、終点を |V|1|V|−1 とする。

    uiui, vivi, cici, didi はフローネットワーク GG の ii 番目の辺を表し、頂点 uiui から頂点 vivi に向かって容量が cici でコストが didi の辺があることを表す。

    出力

    最小費用流を1行に出力する。ただし、始点 ss から終点 tt へ流量 FF のフローを流すことができない場合は -1 を1行に出力する。

    制約

    • 2 ≤ |V||V| ≤ 100
    • 1 ≤ |E||E| ≤ 1000
    • 0 ≤ FF ≤ 1000
    • 0 ≤ cici, didi ≤ 1000
    • uiui ≠ vivi
    • 頂点 xx から頂点 yy に向かって辺がある場合、頂点 yy から頂点 xx に向かう辺(逆辺)はない。

    入力例

    4 5 2
    0 1 2 1
    0 2 1 2
    1 2 1 1
    1 3 1 3
    2 3 2 1
    

    出力例

    6
      1 #include <bits/stdc++.h>
      2 
      3 #define fread_siz 1024
      4 
      5 inline int get_c(void)
      6 {
      7     static char buf[fread_siz];
      8     static char *head = buf + fread_siz;
      9     static char *tail = buf + fread_siz;
     10 
     11     if (head == tail)
     12         fread(head = buf, 1, fread_siz, stdin);
     13 
     14     return *head++;
     15 }
     16 
     17 inline int get_i(void)
     18 {
     19     register int ret = 0;
     20     register int neg = false;
     21     register int bit = get_c();
     22 
     23     for (; bit < 48; bit = get_c())
     24         if (bit == '-')neg ^= true;
     25 
     26     for (; bit > 47; bit = get_c())
     27         ret = ret * 10 + bit - 48;
     28 
     29     return neg ? -ret : ret;
     30 }
     31 
     32 template <class T>
     33 inline T min(T a, T b)
     34 {
     35     return a < b ? a : b;
     36 }
     37 
     38 const int inf = 2e9;
     39 const int maxn = 2005;
     40 
     41 int n, m;
     42 int s, t;
     43 int flow;
     44 
     45 int edges;
     46 int hd[maxn];
     47 int nt[maxn];
     48 int to[maxn];
     49 int vl[maxn];
     50 int fl[maxn];
     51 
     52 inline void add(int u, int v, int f, int w)
     53 {
     54     nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; vl[edges] = +w; hd[u] = edges++;
     55     nt[edges] = hd[v]; to[edges] = u; fl[edges] = 0; vl[edges] = -w; hd[v] = edges++;
     56 }
     57 
     58 int dis[maxn];
     59 int pre[maxn];
     60 
     61 inline bool spfa(void)
     62 {
     63     static int que[maxn];
     64     static int inq[maxn];
     65     static int head, tail;
     66     
     67     memset(dis, 0x3f, sizeof(dis));
     68     head = 0, tail = 0;
     69     que[tail++] = s;
     70     pre[s] = -1;
     71     inq[s] = 1;
     72     dis[s] = 0;
     73     
     74     while (head != tail)
     75     {
     76         int u = que[head++], v; inq[u] = 0;
     77         
     78         for (int i = hd[u]; ~i; i = nt[i])
     79             if (dis[v = to[i]] > dis[u] + vl[i] && fl[i])
     80             {
     81                 dis[v] = dis[u] + vl[i];
     82                 pre[v] = i ^ 1;
     83                 if (!inq[v])
     84                     inq[v] = 1, que[tail++] = v;
     85             }
     86     }
     87     
     88     return dis[t] < 0x3f3f3f3f;
     89 }
     90 
     91 inline int expend(void)
     92 {
     93     int newFlow = inf;
     94     
     95     for (int i = pre[t]; ~i; i = pre[to[i]])
     96         newFlow = min(newFlow, fl[i ^ 1]);
     97         
     98     for (int i = pre[t]; ~i; i = pre[to[i]])
     99         fl[i] += newFlow, fl[i^1] -= newFlow;
    100         
    101     return flow -= newFlow, newFlow * dis[t];
    102 }
    103 
    104 inline int mcmf(void)
    105 {
    106     int ret = 0;
    107     
    108     while (spfa())
    109         ret += expend();
    110         
    111     return flow ? -1 : ret;
    112 }
    113 
    114 signed main(void)
    115 {
    116     n = get_i();
    117     m = get_i();
    118     
    119     flow = get_i();
    120     
    121     memset(hd, -1, sizeof(hd));
    122     
    123     for (int i = 1; i <= m; ++i)
    124     {
    125         int u = get_i();
    126         int v = get_i();
    127         int f = get_i();
    128         int w = get_i();
    129         add(u, v, f, w);
    130     }
    131     
    132     s = n, t = n - 1;
    133     
    134     add(s, 0, flow, 0);
    135     
    136     printf("%d
    ", mcmf());
    137 }

    @Author: YouSiki

  • 相关阅读:
    《C++ Primer(中文版)(第5版)》斯坦利·李普曼 (Stanley B. Lippman) (作者), 约瑟·拉乔伊 (Josee Lajoie) (作者), 芭芭拉·默 (Barbara E. Moo) (作者) azw3
    《O’Reilly精品图书系列共21册》azw3
    《跟老齐学Python:从入门到精通》齐伟(编著)epub+mobi+azw3
    《C Primer Plus(第6版)(中文版)》普拉达(作者)epub+mobi+azw3
    《算法图解》[美] Aditya Bhargava(作者)epub+mobi
    《程序之美系列(套装共6册)》[美]斯宾耐立思 等 (作者) epub+mobi+azw3
    《算法技术手册》George T. Heineman(作者)epub+mobi+azw3
    收藏夹
    笔记
    Unity3D物理引擎Rigidbody,Collider,PhysicMaterial的整理 [转]
  • 原文地址:https://www.cnblogs.com/yousiki/p/6227524.html
Copyright © 2020-2023  润新知