Network Flow

Description

A C++ implementation of Dinic's algorithm for max-flow. Here is a summary of operations:

  • FlowNetwork f(n, m): new network with n vertices (0 to n-1) and m directed edges,
  • f.add(x, y, c) : add directed edge from node x to node y with capacity c,
  • f.flow(s, t) : compute max-flow/min-cut from vertex s to vertex t.

Implementation:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;
const long long INF = (1ll << 60);

class FlowNetwork
{   vector<int> last, to, prev;
    vector<long long> c, f;
    int n, m, id;

    void add_aux(int x, int y, long long w)
    {   prev[id] = last[x];
        last[x] = id;
        to[id] = y;
        c[id] = w;
        id = id + 1;
    }

    /* find blocking flow */
    long long dfs(int x, int t, vector<int> &level, long long need = INF)
    {   if(need <= 0) return 0;
        if(x == t) return need;
        long long can = 0;
        for(int i = last[x]; i != -1; i = prev[i])
        {   int y = to[i];
            if(level[y] == 1 + level[x] && c[i] > f[i])
            {   long long a = dfs(y, t, level, min(c[i]-f[i], need - can));
                f[i] += a;
                f[i^1] -= a;
                can += a;
            }
        }
        if(can == 0) level[x] = -1;
        return can;
    }

    public:
    FlowNetwork(int n_, int m_)
    {   n = n_, m = 2 * m_;

        last.resize(n);
        to.resize(m);
        prev.resize(m);
        c.resize(m);
        f.resize(m);

        fill(last.begin(), last.end(), -1);
        id = 0;
    }

    void print_flow()
    {   for(int i = 0; i < n; i++)
        {   for(int j = last[i]; j != -1; j = prev[j])
            {   if(f[j] <= 0) continue;
                cout << "(" << i << "," << to[j] << ": " << f[j] << ")" << endl;
            }
        }
    }

    /* add directed edge (x,y) with capacity w */
    void add(int x, int y, long long w)
    {   add_aux(x, y, w);
        add_aux(y, x, 0);
    }

    /* compute maximum flow */
    long long flow(int s, int t)
    {   fill(f.begin(), f.end(), 0);

        long long mx_f = 0;
        vector<int> level(n);

        while(1)
        {   fill(level.begin(), level.end(), -1);
            queue<int> q;

            level[s] = 0;
            q.push(s);

            while(q.empty() == false)
            {   int x = q.front(); q.pop();
                for(int i = last[x]; i != -1; i = prev[i])
                {   int y = to[i];
                    if(level[y] == -1 && c[i] > f[i])
                    {   level[y] = 1 + level[x];
                        q.push(y);
                    }
                }
            }

            if(level[t] == -1) break;
            mx_f += dfs(s, t, level);
        }

        return mx_f;
    }
};

int main(void)
{   return 0;
}

results matching ""

    No results matching ""