Cod sursa(job #1828300)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 13 decembrie 2016 01:01:15
Problema Algola Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.82 kb
#include <bits/stdc++.h>

using namespace std;

const int INF = numeric_limits <int> :: max();
const int NMAX = 52;
const int TMAX = 100;
const int VMAX = NMAX * TMAX;

int n, k;
int src;
int snk;
vector <int> G[VMAX];
vector <pair <int, int>> T[NMAX];

int m;
int fi_edge[VMAX];
int se_edge[VMAX];
int fl[VMAX];
int cp[VMAX];

inline void Link(int u, int v, int c) {
    fi_edge[m] = u;
    se_edge[m] = v;
    fl[m] = 0;
    cp[m] = c;
    G[u].push_back(m);
    m++;

    fi_edge[m] = v;
    se_edge[m] = u;
    fl[m] = 0;
    cp[m] = 0;
    G[v].push_back(m);
    m++;
}

inline int Enc(int u, int t) {
    return (u - 1) * TMAX + t;
}

int bfs_parent[VMAX];
queue <int> Q;

bool findPath() {
    memset(bfs_parent, -1, sizeof bfs_parent);
    bfs_parent[src] = 0;
    for (Q.push(src); Q.empty() == false; Q.pop()) {
        int u = Q.front();
        if (u != snk) {
            for (int i: G[u]) {
                if (fl[i] < cp[i] && bfs_parent[se_edge[i]] == -1) {
                    bfs_parent[se_edge[i]] = i;
                    Q.push(se_edge[i]);
                }
            }
        }
    }
    return (bfs_parent[snk] != -1);
}

int pushFlow() {
    if (findPath() == false) {
        return 0;
    }
    else {
        int fl_pushed = 0;
        for (int i: G[snk]) {
            if (bfs_parent[se_edge[i]] != -1) {
                bfs_parent[snk] = i ^ 1;
                int to_inc = INF;
                for (int j = bfs_parent[snk]; j != 0; j = bfs_parent[fi_edge[j]]) {
                    to_inc = min(to_inc, cp[j] - fl[j]);
                }
                for (int j = bfs_parent[snk]; j != 0; j = bfs_parent[fi_edge[j]]) {
                    fl[j] += to_inc;
                    fl[j ^ 1] -= to_inc;
                }
                fl_pushed += to_inc;
            }
        }
        return fl_pushed;
    }
}

int main() {
    ifstream f("algola.in");
    ofstream g("algola.out");

    src = VMAX - 1;
    snk = VMAX - 2;

    f >> n >> k;
    int people = 0;
    for (int i = 1; i <= n; i++) {
        int v;
        f >> v;
        Link(src, Enc(i, 0), v);
        people += v;
    }
    Link(Enc(1, 0), snk, INF);
    while (k--) {
        int u, v, c;
        f >> u >> v >> c;
        T[u].push_back({v, c});
        T[v].push_back({u, c});
    }

    int crt_time = 0;
    int flow = 0;
    while (flow < people) {
        for (int i = 1; i <= n; i++) {
            Link(Enc(i, crt_time), Enc(i, crt_time + 1), INF);
            for (pair <int, int> &e: T[i]) {
                int v = e.first;
                int c = e.second;
                Link(Enc(i, crt_time), Enc(v, crt_time + 1), c);
            }
        }
        Link(Enc(1, crt_time + 1), snk, INF);
        crt_time++;

        int f = 0;
        do {
            f = pushFlow();
            flow += f;
        } while (f != 0);
    }

    g << crt_time << "\n";
    return 0;
}