Cod sursa(job #2391037)

Utilizator MateiTrandafirMatei Trandafir MateiTrandafir Data 28 martie 2019 16:59:12
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <fstream>
#include <cstring>
#include <algorithm>

constexpr int MAX_N = 1001, MAX_M = 20001, INF = 0x7FFFFFFF;

int n, m;
int list[MAX_N], start[MAX_N], next[MAX_M], at[MAX_M], indexes[MAX_M], count;
int c[MAX_N][MAX_N], f[MAX_N][MAX_N];

inline void add(int from, int to, int index) {
    ++count;
    at[count] = to;
    indexes[count] = index;
    next[count] = list[from];
    list[from] = count;
}

int level[MAX_N], q[MAX_N], st, dr;

inline bool bfs() {
    std::memset(level, 0xff, sizeof(level));
    st = dr = 0;
    q[0] = 1;
    level[1] = 0;
    int p, x, y;
    while (st <= dr) {
        x = q[st++];
        for (p = list[x]; p != 0; p = next[p]) {
            y = at[p];
            if (level[y] == -1 && f[x][y] < c[x][y]) {
                level[y] = level[x] + 1;
                q[++dr] = y;
            }
        }
    }
    return level[n] != -1;
}

int flux(int x, int fMin) {
    if (x == n) return fMin;
    int y, fMin2;
    for (; start[x] != 0; start[x] = next[start[x]]) {
        y = at[start[x]];
        if (level[y] == level[x] + 1 && f[x][y] < c[x][y]) {
            fMin2 = flux(y, std::min(fMin, c[x][y] - f[x][y]));
            if (fMin2 > 0) {
                f[x][y] += fMin2;
                f[y][x] -= fMin2;
                return fMin2;
            }
        }
    }
    return 0;
}

inline void dBfs() {
    std::memset(level, 0xff, sizeof(level));
    st = dr = 0;
    q[0] = n;
    level[n] = 0;
    int x, y, p;
    while (st <= dr) {
        x = q[st++];
        for (p = list[x]; p != 0; p = next[p]) {
            y = at[p];
            if (level[y] == -1 && f[y][x] < c[y][x]) {
                level[y] = level[x] + 1;
                q[++dr] = y;
            }
        }
    }
}

int res[MAX_M], resCount;

inline void rBfs() {
    st = dr = 0;
    q[0] = 1;
    level[1] = -2;
    int x, y, p;
    while (st <= dr) {
        x = q[st++];
        for (p = list[x]; p != 0; p = next[p]) {
            y = at[p];
            if (level[y] == -1 && f[x][y] < c[x][y]) {
                level[y] = -2;
                q[++dr] = y;
            } else if (level[y] >= 0 && f[x][y] == c[x][y]) res[resCount++] = indexes[p];
        }
    }
}

int main() {
    std::ifstream in("critice.in");
    std::ofstream out("critice.out");
    int i, x, y, z;
    in >> n >> m;
    for (i = 1; i <= m; ++i) {
        in >> x >> y >> z;
        add(x, y, i);
        c[x][y] = z;
        add(y, x, i);
        c[y][x] = z;
    }
    int fc;
    while (bfs()) {
        for (i = 1; i <= n; ++i) start[i] = list[i];
        do fc = flux(1, INF);
        while (fc != 0);
    }
    dBfs();
    rBfs();
    std::sort(res, res + resCount);
    out << resCount;
    for (i = 0; i < resCount; ++i) out << '\n' << res[i];
    return 0;
}