Cod sursa(job #1873444)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 9 februarie 2017 01:42:43
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fi("critice.in");
ofstream fo("critice.out");

const int NMAX = 1005;

vector<pair<int, int>> edg;
vector<int> ant;
int n, m;

vector<int> g[NMAX];
int flow[NMAX][NMAX],
     cap[NMAX][NMAX],
     far[NMAX],
     gws[NMAX];

void pump(int src, int snk) {
    deque<int> q;
    int it, aug, u;

    while (true) {
        q.push_back(src);
        gws[src] = ++it;

        while (!q.empty()) {
            u = q.front();
            q.pop_front();

            for (auto v: g[u]) if (gws[v] != it && cap[u][v] - flow[u][v] > 0) {
                q.push_back(v);
                gws[v] = it;
                far[v] = u; } }

        if (gws[snk] < it)
            return;

        for (auto v: g[snk]) {
            aug = cap[v][snk] - flow[v][snk];

            for (int nod = v; nod != src; nod = far[nod])
                aug = min(aug, cap[far[nod]][nod] - flow[far[nod]][nod]);

            for (int nod = v; nod != src; nod = far[nod]) {
                flow[far[nod]][nod]+= aug;
                flow[nod][far[nod]]-= aug; }

            flow[v][snk]+= aug;
            flow[snk][v]-= aug; } } }

int god(int nod) {
    if (far[nod] == nod)
        return nod;
    return (far[nod] = god(far[nod])); }

int join(int a, int b) {
    a = god(a);
    b = god(b);
    far[a] = b; }

int main(void) {
    int srcs, snks, x, y, c, s;

    fi >> n >> m;
    edg.resize(m);
    for (auto &e: edg) {
        fi >> e.first >> e.second >> c;
        g[e.first].push_back(e.second), cap[e.first][e.second]+= c;
        g[e.second].push_back(e.first), cap[e.second][e.first]+= c; }

    pump(1, n);
    for (int i = 1; i <= n; ++i)
        far[i] = i;

    for (int e = 0; e < edg.size(); ++e)
        if (cap[edg[e].first][edg[e].second] != abs(flow[edg[e].first][edg[e].second]))
            join(edg[e].first, edg[e].second);

    for (int e = 0; e < edg.size(); ++e)
        if (cap[edg[e].first][edg[e].second] == abs(flow[edg[e].first][edg[e].second])) {
            x = god(edg[e].first);
            y = god(edg[e].second);
            if (x == god(1) && y == god(n))
                ant.push_back(e + 1);
            else if (y == god(1) && x == god(n))
                ant.push_back(e + 1); }

    fo << ant.size() << '\n';
    for (auto e: ant)
        fo << e << '\n';

    return 0; }