Cod sursa(job #2827731)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 6 ianuarie 2022 11:42:29
Problema Critice Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <bits/stdc++.h>

using namespace std;
#ifdef INFOARENA
#define cin fin
#define cout fout
ifstream fin("critice.in");
ofstream fout("critice.out");
#endif // INFOARENA
using ll = long long;
const int max_flow = 1e9;
class Flow {
    struct Edge {
        int from, to, cap;
        Edge(int u, int v, int w) : from(u), to(v), cap(w) {}
    };
    int n, s, t, k;
    vector <int> lvl, rem;
    vector <vector <int>> g;
    vector <Edge> edges;
    vector <int> crit;
public:
    Flow(int _n, int S, int T) : n(_n), s(S), t(T), k(0), lvl(n + 1), g(n + 1), rem(n + 1) {}
    void add_edge(int u, int v, int w, int rw = 0) {
        edges.emplace_back(u, v, w);
        edges.emplace_back(v, u, rw);
        g[u].push_back(k++);
        g[v].push_back(k++);
    }
    bool bfs() {
        fill(lvl.begin(), lvl.end(), 0);
        queue <int> q;
        for(q.push(s), lvl[s] = 1; !q.empty(); q.pop()) {
            int u = q.front();
            for(int id : g[u]) {
                int v = edges[id].to;
                if(edges[id].cap && !lvl[v])
                    q.push(v),
                    lvl[v] = lvl[u] + 1;
            }
        }
        return lvl[t];
    }
    int dfs(int u, int flow) {
        if(!flow || u == t) return flow;
        for(int& cid = rem[u]; cid < g[u].size(); cid++) {
            int id = g[u][cid];
            int v = edges[id].to;
            if(!edges[id].cap || lvl[v] != lvl[u] + 1) continue;
            int f = dfs(v, min(flow, edges[id].cap));
            if(!f) continue;
            edges[id].cap -= f;
            edges[id ^ 1].cap += f;
            return f;
        }
        return 0;
    }
    ll dinic() {
        ll flow = 0;
        while(bfs()) {
            fill(rem.begin(), rem.end(), 0);
            while(int f = dfs(s, max_flow))
                flow += f;
        }
        return flow;
    }
    void residual_bfs() {
        fill(lvl.begin(), lvl.end(), 0);
        queue <int> q;
        for(q.push(t), lvl[t] = 1; !q.empty(); q.pop()) {
            int u = q.front();
            for(int id : g[u]) {
                int v = edges[id].to;
                if(!lvl[v] && edges[id ^ 1].cap)
                    q.push(v),
                    lvl[v] = 1;
            }
        }
    }
    void bfs_crit() {
        queue <int> q;
        for(q.push(s), lvl[s] = 2; !q.empty(); q.pop()) {
            int u = q.front();
            for(int id : g[u]) {
                int v = edges[id].to;
                if(edges[id].cap && !lvl[v]) {
                    lvl[v] = 2;
                    q.push(v);
                }
                if(lvl[v] == 1 && !edges[id].cap) crit.push_back(id / 2 + 1);
            }
        }
    }
    vector <int> critical() {
        dinic();
        residual_bfs();
        bfs_crit();
        return crit;
    }
};

int main()
{
    int n, m, u, v, w;
    cin >> n >> m;
    Flow f(n, 1, n);
    for(int i = 0; i < m; i++)
        cin >> u >> v >> w,
        f.add_edge(u, v, w);
    vector <int> sol = f.critical();
    cout << sol.size() << "\n";
    for(int x : sol) cout << x << "\n";
    return 0;
}