Cod sursa(job #2554388)

Utilizator iliaaaaaaaaaaaaaailia petrov iliaaaaaaaaaaaaaa Data 22 februarie 2020 21:00:02
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.35 kb
#include <iostream>
#include <cstring>
#include <queue>
#include <fstream>

const int MAXN = 1024;
const long long INF = 1e9;

struct edge {
    int from, to, capacity, last;
};

int last[MAXN], level[MAXN];
edge edges[10 * MAXN];

long long dfs(int s, int t, int currcap, int copylast[])
{
    //std::cout << s << ' ' << currcap << '\n';
    if(s == t)
    {
        return currcap;
    }
    if(copylast[s] == -1)
    {
        return 0;
    }

    long long ans = 0, ind = copylast[s];
    auto edg = edges[copylast[s]];
    bool is = false;

    while(true)
    {
        if(!currcap)
        {
            break;
        }
        if(level[edg.to] == level[edg.from] + 1)
        {
            int currv = dfs(edg.to, t, std::min(currcap, edg.capacity), copylast);
            if(currv != 0)
            {
                is = true;
                ans += currv;
                edges[ind].capacity -= currv;
                edges[ind ^ 1].capacity += currv;
                currcap -= currv;
            }
        }

        if(!is)
        {
            copylast[edg.from] = ind;
        }

        if(edg.last == -1)
        {
            break;
        }
        ind = edg.last;
        edg = edges[edg.last];
    }

    return ans;
}

long long bfs(int s, int t)
{
    memset(level, -1, sizeof(level));
    std::queue<int> k;
    int copylast[MAXN];
    for(int i = 0; i < MAXN; ++ i)
    {
        copylast[i] = last[i];
    }
    k.push(s);
    level[s] = 0;

    while(!k.empty())
    {
        int curr = k.front();
        k.pop();

        if(curr == t)
        {
            break;
        }

        auto edg = edges[last[curr]];

        while(true)
        {
            if(edg.capacity != 0)
            {
                if(level[edg.to] == -1)
                {
                    k.push(edg.to);
                    level[edg.to] = level[edg.from] + 1;
                }
                if(level[edg.to] > level[edg.from] + 1)
                {
                    level[edg.to] = level[edg.from] + 1;
                }
            }
            if(edg.last == -1)
            {
                break;
            }
            edg = edges[edg.last];
        }
    }

    /*for(int i = 1; i <= t; ++ i)
    {
        std::cout << level[i] << ' ';
    }std::cout << '\n';*/

    return dfs(s, t, INF, copylast);
}

int main()
{
    #define cout myfileOut
    std::ofstream myfileOut;
    myfileOut.open ("maxflow.out");

    #define cin myFileIn
    std::ifstream myFileIn;
    myFileIn.open ("maxflow.in");

    memset(last, -1, sizeof(last));
    int n, m;
    cin >> n >> m;

    for(int i = 0; i < m; ++ i)
    {
        int u, v, c;
        cin >> u >> v >> c;

        edges[i * 2] = {u, v, c, last[u]};
        last[u] = i * 2;
        edges[i * 2 + 1] = {v, u, 0, last[v]};
        last[v] = i * 2 + 1;
    }

    /*for(int i = 0; i < 2 * m; ++ i)
    {
        std::cout << edges[i].from << ' ' << edges[i].to << ' ' << edges[i].capacity << ' ' << edges[i].last << '\n';
    }*/

    long long ans = 0;

    while(true)
    {
        long long curr = bfs(1, n);
        if(curr)
        {
            ans += curr;
        }else
        {
            cout << ans << '\n';
            return 0;
        }
    }

    return 0;
}