Cod sursa(job #2586422)

Utilizator IulianOleniucIulian Oleniuc IulianOleniuc Data 20 martie 2020 20:41:53
Problema Critice Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <bits/stdc++.h>
using namespace std;

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

class FlowNetwork {
  private:
    int n, s, t;
    vector<vector<int>> ad, edg, cap;

    bool bfs(vector<bool>& vis, vector<int>& father) {
        fill(vis.begin(), vis.end(), false);
        vis[s] = true;
        queue<int> q; q.push(s);
        while (!q.empty()) {
            int node = q.front(); q.pop();
            for (int nghb : ad[node])
                if (!vis[nghb] && cap[node][nghb]) {
                    vis[nghb] = true;
                    father[nghb] = node;
                    if (nghb != t)
                        q.push(nghb);
                }
        }
        return vis[t];
    }

    void dfs(int node, vector<bool>& vis) {
        vis[node] = true;
        for (int i = 1; i <= n; i++)
            if (cap[node][i] && !vis[i])
                dfs(i, vis);
    }

  public:
    FlowNetwork(int n, int s, int t) :
        n(n), s(s), t(t), ad(n + 1),
        edg(n + 1, vector<int>(n + 1)),
        cap(n + 1, vector<int>(n + 1)) { }

    void addEdge(int x, int y, int z = 1) {
        static int id = 0;
        ad[x].push_back(y);
        ad[y].push_back(x);
        cap[x][y] = cap[y][x] = z;
        edg[x][y] = edg[y][x] = ++id;
    }

    void maxFlow() {
        vector<bool> vis(n + 1);
        vector<int> father(n + 1);
        while (bfs(vis, father))
            for (int nghb : ad[t])
                if (vis[nghb] && cap[nghb][t]) {
                    int flow = 1e9;
                    father[t] = nghb;
                    for (int i = t; i != s; i = father[i])
                        flow = min(flow, cap[father[i]][i]);
                    for (int i = t; i != s; i = father[i]) {
                        cap[father[i]][i] -= flow;
                        cap[i][father[i]] += flow;
                    }
                }
    }

    auto criticalEdges() {
        vector<bool> visS(n + 1); dfs(s, visS);
        vector<bool> visT(n + 1); dfs(t, visT);
        vector<int> edges;
        for (int i = 1; i <= n; i++)
            for (int j = i + 1; j <= n; j++)
                if (edg[i][j] && (!cap[i][j] || !cap[j][i]) && ((visS[i] && visT[j]) || (visS[j] && visT[i])))
                    edges.push_back(edg[i][j]);
        sort(edges.begin(), edges.end());
        return edges;
    }
};

int main() {
    int n, m; fin >> n >> m;
    FlowNetwork graph(n, 1, n);
    for (int i = 0; i < m; i++) {
        int x, y, z; fin >> x >> y >> z;
        graph.addEdge(x, y, z);
    }

    graph.maxFlow();
    auto edges = graph.criticalEdges();
    fout << edges.size() << '\n';
    for (int edge : edges)
        fout << edge << '\n';

    fout.close();
    return 0;
}