Cod sursa(job #1759805)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 19 septembrie 2016 20:59:41
Problema Flux maxim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

int N, M;
int h[1005], e[1005];
int cp[1005][1005];
vector <int> edg[1005];
vector <int> nodes;

void addEdge(int x, int y, int cap)
{
    if(cp[x][y] == 0 && cp[y][x] == 0)
    {
        edg[x].push_back(y);
        edg[y].push_back(x);
    }
    cp[x][y] += cap;
}

void preflow(int s)
{
    memset(h, 0, sizeof(h));
    memset(e, 0, sizeof(e));

    for(auto nxt: edg[s])
    {
        e[nxt] += cp[s][nxt];
        cp[nxt][s] = cp[s][nxt];
        cp[s][nxt] = 0;
    }
    h[s] = N;
}

bool cmp(int a, int b)
{
    return e[a] > e[b];
}

void push(int nod)
{
    bool ok = 0;
    for(auto nxt: edg[nod])
        if(h[nod] == h[nxt] + 1 && cp[nod][nxt] > 0)
        {
            ok = 1;
            int add = min(e[nod], cp[nod][nxt]);
            e[nod] -= add;
            e[nxt] += add;
            cp[nod][nxt] -= add;
            cp[nxt][nod] += add;
        }
}

void relabel(int nod)
{
    int hmin = 2 * N;
    for(auto nxt: edg[nod])
        if(cp[nod][nxt])
            hmin = min(hmin, h[nxt]);
    h[nod] = hmin + 1;
}

bool discharge(int nod)
{
    push(nod);
    if(e[nod])
    {
        relabel(nod);
        return 1;
    }
    return 0;
}

int getMaxFlow(int s, int t)
{
    preflow(s);

    for(int i = 1; i <= N; i++)
        if(i != s && i != t)
            nodes.push_back(i);
    sort(nodes.begin(), nodes.end(), cmp);

    bool ok = 1;
    while(ok)
    {
        ok = 0;
        for(int i = 0, nod = nodes[i]; i < nodes.size(); i++, nod = nodes[i])
            if(e[nod])
            {
                ok = 1;
                bool relabeled = discharge(nod);
                if(relabeled)
                {
                    nodes.erase(nodes.begin() + i);
                    nodes.insert(nodes.begin(), nod);
                    break;
                }
            }
    }

    return e[t];
}

int main()
{
    #ifdef FILE_IO
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);
    #endif

    scanf("%d%d", &N, &M);
    memset(cp, 0, sizeof(cp));
    for(int i = 1; i <= M; i++)
    {
        int x, y, cap;
        scanf("%d%d%d", &x, &y, &cap);
        addEdge(x, y, cap);
    }

    int ans = getMaxFlow(1, N);

    printf("%d\n", ans);

    return 0;
}