Cod sursa(job #1425229)

Utilizator Eugen01Vasilescu Eugen Eugen01 Data 27 aprilie 2015 01:10:46
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

#define Nmax 1005
#define inf 0x3f3f3f3f

std::ifstream in("critice.in");
std::ofstream out("critice.out");

std::vector<int> G[Nmax], G2[Nmax];
int F[Nmax][Nmax], C[Nmax][Nmax], T[Nmax], result[Nmax];
bool checked[Nmax];
std::vector<std::pair<int, int> > edges;

void BFS2(int source, int x) {
    std::queue<int> Q;
    Q.push(source);
    memset(checked, false, sizeof(checked));
    checked[source] = true;
    result[source] += x;

    while (!Q.empty()) {
        int node = Q.front();
        Q.pop();

        for (int i = 0; i < G2[node].size(); i++) {
            int nextNode = G2[node][i];

            if (checked[nextNode]) continue;
            checked[nextNode] = true;

            Q.push(nextNode);
            result[nextNode] += x;
        }
    }
}

bool BFS(int source, int destination) {
    std::queue<int> Q;
    Q.push(source);
    memset(checked, false, sizeof(checked));

    while (!Q.empty()) {
        int node = Q.front();
        Q.pop();

        for (int i = 0; i < G[node].size(); i++) {
            int nextNode = G[node][i];

            if (checked[nextNode]) continue;
            if (F[node][nextNode] == C[node][nextNode]) continue;

            checked[nextNode] = true;
            if (nextNode == destination) continue;

            T[nextNode] = node;
            Q.push(nextNode);
        }
    }

    return checked[destination];
}

int main() {
    int N, M;
    in >> N >> M;

    for (int i = 1; i <= M; i++) {
        int x, y, c;
        in >> x >> y >> c;

        G[x].push_back(y);
        G[y].push_back(x);

        C[x][y] = C[y][x] = c;
        edges.push_back(std::make_pair(x, y));
    }

    int totalFlow = 0;
    while (BFS(1, N)) {
        for (int i = 0; i < G[N].size(); i++) {
            T[N] = G[N][i];

            int flow = inf, node = N;
            while (node != 1) {
                flow = std::min(flow, C[T[node]][node] - F[T[node]][node]);
                node = T[node];
            }

            if (flow <= 0) continue;
            totalFlow += flow;

            node = N;
            while (node != 1) {
                F[T[node]][node] += flow;
                F[node][T[node]] -= flow;

                node = T[node];
            }
        }
    }

    for (int i = 1; i <= N; i++)
        for (int j = 0; j < G[i].size(); j++) {
            int node = i;
            int nextNode = G[i][j];

            if (F[node][nextNode] == C[node][nextNode]) continue;
            if (F[nextNode][node] == C[nextNode][node]) continue;

            G2[i].push_back(nextNode);
        }

    BFS2(1, 1);
    BFS2(N, 2);

    std::vector<int> sol;
    for (int i = 0; i < edges.size(); i++) {
        int node1 = edges[i].first;
        int node2 = edges[i].second;

        if ((result[node1] & 1) && (result[node2] & 2)) sol.push_back(i + 1);
        else if ((result[node1] & 2) && (result[node2] & 1)) sol.push_back(i + 1);
    }

    out << sol.size() << "\n";
    for (int i = 0; i < sol.size(); i++)
        out << sol[i] << "\n";
}