Cod sursa(job #2717976)

Utilizator alextodoranTodoran Alexandru Raul alextodoran Data 8 martie 2021 11:37:13
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.02 kb
/**
 ____ ____ ____ ____ ____
||a |||t |||o |||d |||o ||
||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|

**/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct Flow
{
    const int INF = INT_MAX / 2;

    struct Edge
    {
        int u, v;
        int capacity;
        int rev;
    };

    int n;
    vector <Edge> edges;
    vector <vector <int>> adj;
    vector <int> rev;

    Flow (int _n)
    {
        n = _n;
        edges.clear();
        rev.clear();
        adj.resize(n);
        for(int i = 0; i < n; i++)
            adj[i].clear();
    }

    void addEdge (int u, int v, int capacity)
    {
        u--;
        v--;
        edges.push_back(Edge{u, v, capacity, 0});
        edges.push_back(Edge{v, u, 0, 0});
        adj[u].push_back((int)edges.size() - 2);
        adj[v].push_back((int)edges.size() - 1);
        edges.end()[-2].rev = (int)edges.size() - 1;
        edges.end()[-1].rev = (int)edges.size() - 2;
    }

    vector <int> level;
    vector <int> first;

    bool bfs ()
    {
        level.resize(n);
        for(int i = 0; i < n; i++)
            level[i] = -1;
        queue <int> q;
        level[0] = 0;
        q.push(0);
        while(q.empty() == false)
        {
            int u = q.front();
            q.pop();
            for(int i : adj[u])
                if(edges[i].capacity > 0)
                {
                    if(level[edges[i].v] == -1)
                    {
                        level[edges[i].v] = level[u] + 1;
                        q.push(edges[i].v);
                    }
                }
        }
        return level[n - 1] != -1;
    }

    int dfs (int u, int pushed)
    {
        if(u == n - 1)
            return pushed;
        while(first[u] < (int)adj[u].size())
        {
            int i = adj[u][first[u]];
            first[u]++;
            if(level[u] + 1 == level[edges[i].v] && edges[i].capacity > 0)
            {
                int push = dfs(edges[i].v, min(pushed, edges[i].capacity));
                if(push == 0)
                    continue;
                edges[i].capacity -= push;
                edges[edges[i].rev].capacity += push;
                return push;
            }
        }
        return 0;
    }

    int maxFlow ()
    {
        int answer = 0;
        first.resize(n);
        while(bfs() == true)
        {
            for(int i = 0; i < n; i++)
                first[i] = 0;
            while(true)
            {
                int push = dfs(0, INF);
                if(push == 0)
                    break;
                answer += push;
            }
        }
        return answer;
    }
};

int n, m;

int main()
{
    ifstream fin ("maxflow.in");
    ofstream fout ("maxflow.out");
    fin >> n >> m;
    Flow f(n);
    for(int i = 1; i <= m; i++)
    {
        int u, v, c;
        fin >> u >> v >> c;
        f.addEdge(u, v, c);
    }
    fout << f.maxFlow() << "\n";
    return 0;
}