Cod sursa(job #1946603)

Utilizator razvan242Zoltan Razvan-Daniel razvan242 Data 30 martie 2017 11:33:10
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin("critice.in");
ofstream fout("critice.out");

const int NMAX = 1001;

int n, m;
int c[NMAX][NMAX], f[NMAX][NMAX];
vector<vector<int> > v;
vector<pair<int, int> > edges;
vector<bool> seen, viz1, viz2;
vector<int> t;

inline void read() {
    fin >> n >> m;
    v = vector<vector<int> >(n + 1);
    edges = vector<pair<int, int> >(m + 1);
    seen = viz1 = viz2 = vector<bool>(n + 1);
    t = vector<int>(n + 1);
    int x, y, w;
    for (int i = 1; i <= m; ++i) {
        fin >> x >> y >> w;
        v[x].push_back(y);
        v[y].push_back(x);
        c[x][y] = c[y][x] = w;
        edges[i] = {x, y};
    }
}

inline bool bfs() {
    queue<int> q;
    for (int i = 1; i <= n; ++i)
        seen[i] = 0;
    seen[1] = 1;
    q.push(1);
    int x;
    while (q.size()) {
        x = q.front();
        q.pop();

        if (x == n)
            break;

        for (const int& y: v[x]) {
            if (c[x][y] > f[x][y] && !seen[y]) {
                t[y] = x;
                seen[y] = 1;
                q.push(y);
            }
        }
    }

    return seen[n];
}

inline void getFlow() {
    int minFlow;
    while (bfs()) {
        for (const int& x: v[n]) {
            if (f[x][n] >= c[x][n] || !seen[x])
                continue;
            t[n] = x;
            minFlow = 2e9;

            for (int i = n; i != 1; i = t[i])
                minFlow = min(minFlow, c[t[i]][i] - f[t[i]][i]);
            for (int i = n; i != 1; i = t[i]) {
                f[t[i]][i] += minFlow;
                f[i][t[i]] -= minFlow;
            }
        }
    }
}

inline int abs(int x) {
    return x > 0 ? x : -x;
}

inline void bfs(int node, vector<bool>& viz) {
    queue<int> q;
    q.push(node);
    viz[node] = 1;

    int x;
    while (q.size()) {
        x = q.front();
        q.pop();

        for (const int& y: v[x])
            if (c[x][y] > abs(f[x][y]) && !viz[y]) {
                viz[y] = 1;
                q.push(y);
            }
    }
}

inline void getCriticalEdges() {
    vector<int> ans;
    bfs(1, viz1);
    bfs(n, viz2);

    int x, y;
    for (int i = 1; i <= m; ++i) {
        x = edges[i].first, y = edges[i].second;

        if ((c[x][y] == f[x][y] || c[y][x] == f[y][x]) && ((viz1[x] && viz2[y]) || (viz1[y] && viz2[x])))
            ans.push_back(i);
    }

    fout << ans.size() << '\n';
    for (const int& x: ans)
        fout << x << '\n';
}

int main()
{
    read();
    getFlow();
    getCriticalEdges();

    fin.close();
    fout.close();
    return 0;
}