Cod sursa(job #1654801)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 17 martie 2016 15:07:14
Problema Critice Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.5 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

#define pb push_back
#define si short
#define mp make_pair

int main() {
    ifstream in("critice.in");
    ofstream out("critice.out");

    int n, m;

    in >> n >> m;

    vector < vector < si > > cap(n, vector < si >(n, 0)), flow(n, vector < si >(n, 0));
    vector < vector < pair < si, si > > > adj(n);

    for(int i = 0, a, b, c; i < m; i++) {
        in >> a >> b >> c;
        a--; b--;
        cap[a][b] = c;
        adj[a].pb(mp(b, i));
        adj[b].pb(mp(a, i));
    }

    queue < si > q;
    vector < bool > vis(n, false);
    vector < si > f(n, -1);
    vector < si > sol;
    vector < si > f_edge(n, -1);

    while(true) {
        vis[0] = true;
        f[0] = 0;
        q.push(0);
        while(!q.empty()) {
            const int cur = q.front();
            q.pop();
            if(cur == n - 1) continue;
            for(const auto i : adj[cur]) {
                const int next = i.first;
                const int ind = i.second;
                if(!vis[next] && flow[cur][next] < cap[cur][next]) {
                    vis[next] = 1;
                    f[next] = cur;
                    f_edge[next] = ind;
                    q.push(next);
                }
            }
        }
        if(!vis[n - 1]) break;
        for(const auto edge : adj[n - 1]) {
            const int start = edge.first;
            const int ind = edge.second;
            if(!vis[start]) continue;
            int imin = 0, flowmin = 0x7fffffff;
            f[n - 1] = start;
            f_edge[n - 1] = ind;
            for(int i = n - 1; i != 0; i = f[i]) {
                if(flowmin > cap[f[i]][i] - flow[f[i]][i]) {
                    flowmin = cap[f[i]][i] - flow[f[i]][i];
                    imin = f_edge[i];
                }
                else if(flowmin == cap[f[i]][i] - flow[f[i]][i]) {
                    imin = -1;
                }
            }
            if(flowmin <= 0) continue;
            for(int i = n - 1; i != 0; i = f[i]) {
                flow[f[i]][i] += flowmin;
                flow[i][f[i]] -= flowmin;
            }
            if(imin > 0) {
                sol.pb(imin);
            }
        }
        fill(begin(vis), end(vis), false);
        fill(begin(f), end(f), -1);
        fill(begin(f_edge), end(f_edge), -1);
    }

    out << sol.size() << '\n';
    for(const auto i : sol) out << i + 1 << '\n';
    return 0;
}