Cod sursa(job #2741369)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 15 aprilie 2021 21:57:51
Problema Flux maxim Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.62 kb
#include <bits/stdc++.h>

using namespace std;

#ifndef LOCAL

ifstream in("maxflow.in");
ofstream out("maxflow.out");

#define cin in
#define cout out

#endif //LOCAL

struct Edge
{
    int u, v;
    long long cap, flow;

    Edge(int _u, int _v, int _cap)
    {
        u = _u; v = _v;
        cap = _cap;
        flow = 0;
    }
};

struct Dinic {
    const long long flow_inf = 1e18;
    vector<Edge> edges;
    vector<vector<int>> adj;

    int n, m = 0;
    int s, t;
    vector<int> level, ptr;
    queue<int> q;

    Dinic(int _n, int _s, int _t)
    {
        n = _n; s = _s; t = _t;

        adj.resize(n + 7);
        level.resize(n + 7);
        ptr.resize(n + 7);
    }

    void addEdge(int u, int v, long long cap)
    {
        edges.push_back(Edge(u, v, cap));
        edges.push_back(Edge(v, u, -cap));

        adj[u].push_back(m);
        adj[v].push_back(m + 1);

        m += 2;
    }

    bool bfs()
    {
        while(!q.empty())
        {
            int u = q.front();
            q.pop();

            for(int id : adj[u])
            {
                if(edges[id].cap - edges[id].flow < 1)
                    continue;
                if(level[edges[id].v] != -1)
                    continue;
                level[edges[id].v] = level[u] + 1;
                q.push(edges[id].v);
            }
        }

        return level[t] != -1;
    }

    long long dfs(int u, long long pushed)
    {
        if(pushed == 0)
            return 0;
        if(u == t)
            return pushed;

        for(int& cid = ptr[u]; cid < adj[u].size(); ++cid)
        {
            int id = adj[u][cid];
            int v = edges[id].v;

            if(level[u] + 1 != level[v] || edges[id].cap - edges[id].flow < 1)
                continue;

            long long tr = dfs(v, min(pushed, edges[id].cap - edges[id].flow));

            if(tr == 0)
                continue;

            edges[id].flow += tr;
            edges[id ^ 1].flow -= tr;

            return tr;
        }

        return 0;
    }

    long long flow()
    {
        long long f = 0;
        while(true)
        {
            fill(level.begin(), level.end(), - 1);
            level[s] = 0;
            q.push(s);
            if(!bfs())
                break;

            fill(ptr.begin(), ptr.end(), 0);

            while(long long pushed = dfs(s, flow_inf)) {
                f += pushed;
            }
        }

        return f;
    }
};

int main()
{
    int n, m;
    cin >> n >> m;

    Dinic solver(n + 1, 1, n);

    for(int i = 0; i < m; i++)
    {
        int x, y, c;
        cin >> x >> y >> c;
        solver.addEdge(x, y, c);
    }

    cout << solver.flow() << endl;
}