Cod sursa(job #1007543)

Utilizator toranagahVlad Badelita toranagah Data 9 octombrie 2013 01:23:01
Problema Critice Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <cstring>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

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

const int MAX_N = 1005; 
const int MAX_M = 10100;
const int INF = 1 << 30;

int N, M;
vector<int> graph[MAX_N];
pair<int, int> edges[MAX_M];
bool source_path[MAX_N];
bool sink_path[MAX_N];
int cp[MAX_N][MAX_N];
int incoming[MAX_N];
int source, sink;
vector<int> answer;

void read_input();
void solve();
void print_output();
int maxflow();
bool find_augmenting_path();
void dfs(int start, bool path[]);

int main() {
    read_input();
    solve();
    print_output();
}

void read_input() {
    fin >> N >> M;
    for (int i = 1, a, b, c; i <= M; ++i) {
        fin >> a >> b >> c;
        graph[a].push_back(b);
        graph[b].push_back(a);
        cp[a][b] = c;
        cp[b][a] = c;

        edges[i].first = a;
        edges[i].second = b;
    }
    source = 1;
    sink = N;
}

void solve() {
    maxflow();

    dfs(source, source_path);
    dfs(sink, sink_path);

    for (int i = 1, a, b; i <= M; ++i) {
        a = edges[i].first;
        b = edges[i].second;

        if ((source_path[a] && sink_path[b]) || 
                (sink_path[a] && source_path[b])) {
            answer.push_back(i);
        }
    }
}

void print_output() {
    fout << answer.size() << '\n';
    for (auto node : answer) {
        fout << node << '\n';
    }
}

int maxflow() {
    int result = 0;
    while (find_augmenting_path()) {
        int flow = INF;
        for (int node = sink; node != source; node = incoming[node]) {
            flow = min(flow, cp[incoming[node]][node]);
        }

        for (int node = sink; node != source; node = incoming[node]) {
            cp[incoming[node]][node] -= flow;
            cp[node][incoming[node]] += flow;
        }
        result += flow;

        memset(source_path, 0, sizeof(source_path));
    }
    return result;
}

bool find_augmenting_path() {
    queue<int> q;
    q.push(source);
    source_path[source] = 1;

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

        for (auto next : graph[node]) {
            if (!source_path[next] && cp[node][next] > 0) {
                source_path[next] = 1;
                incoming[next] = node;
                q.push(next);

                if (next == sink) return true;
            }
        }
    }
    return false;
}

void dfs(int node, bool path[]) {
    path[node] = true;
    for (auto next : graph[node]) {
        if (cp[node][next] > 0 && cp[next][node] > 0 && path[next] == false) {
            dfs(next, path);
        }
    }
}