Cod sursa(job #2115659)

Utilizator Mihai_PredaPreda Mihai Dragos Mihai_Preda Data 26 ianuarie 2018 23:19:58
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.17 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <algorithm>

using namespace std;

class flow
{
public:
    flow(int n, int source, int dest)
    {
        this->source = source;
        this->dest = dest;
        this->n = n;
        cap.resize(n + 1, vector<int>(n + 1));
        flux.resize(n + 1, vector<int>(n + 1));
        vecini.resize(n + 1);
        viz.resize(n + 1);
        father.resize(n + 1);
    }
    void AddEdge(int x, int y, int c)
    {
        if(cap[x][y] == 0 && cap[y][x] == 0)
        {
            vecini[x].push_back(y);
            vecini[y].push_back(x);
        }
        cap[x][y] += c;
    }
    int GetMaxFlow()
    {
        int ret = 0;
        BFS();
        while(viz[dest])
        {
            for(auto nod:vecini[dest])
            {
                if(cap[nod][dest] == flux[nod][dest] || viz[nod] == false)
                    continue;
                father[dest] = nod;

                int mn = cap[father[dest]][dest] - flux[father[dest]][dest];
                nod = father[dest];
                while(nod != source)
                {
                    mn = min(mn, cap[father[nod]][nod] - flux[father[nod]][nod]);
                    nod = father[nod];
                }

                nod = dest;
                while(nod != source)
                {
                    flux[father[nod]][nod] += mn;
                    flux[nod][father[nod]] -= mn;
                    nod = father[nod];
                }

                ret += mn;
            }
            BFS();
        }
        return ret;
    }
    void BFS()
    {
        fill(viz.begin(), viz.end(), false);
        queue<int> q;
        q.push(source);
        viz[source] = true;

        while(q.empty() == false)
        {
            int nod = q.front();
            q.pop();
            if(nod == dest)
                continue;

            for(auto v:vecini[nod])
            {
                if(cap[nod][v] == flux[nod][v] || viz[v])
                    continue;
                viz[v] = true;
                q.push(v);
                father[v] = nod;
            }
        }
    }
    void BFSReverse()
    {
        fill(viz.begin(), viz.end(), false);
        queue<int> q;
        q.push(source);
        viz[source] = true;

        while(q.empty() == false)
        {
            int nod = q.front();
            q.pop();
            if(nod == dest)
                continue;

            for(auto v:vecini[nod])
            {
                if(cap[v][nod] == flux[v][nod] || viz[v])
                    continue;
                viz[v] = true;
                q.push(v);
                father[v] = nod;
            }
        }
    }
    void GetMinCut(vector<pair<int, int> > &ret)
    {
        ret.reserve(GetMaxFlow());
        for(int i = 1; i <= n; ++i)
            for(auto j:vecini[i])
                if(viz[i] == true && viz[j] == false)
                    ret.push_back({i, j});
    }
    vector<vector<int> > vecini;
    vector<vector<int> > cap;
    vector<vector<int> > flux;
    vector<bool> viz;
    int source, dest;
private:
    int n;
    vector<int> father;
};


int main()
{
    ifstream in("critice.in");
    int n, m;
    in >> n >> m;
    flow gr(n, 1, n);
    int a, b, c;
    unordered_map<int, unordered_map<int, int> > id;
    for(int i = 1; i <= m; ++i)
    {
        in >> a >> b >> c;
        gr.AddEdge(a, b, c);
        gr.AddEdge(b, a, c);
        id[min(a, b)][max(a,b)] = i;
    }
    in.close();

    gr.GetMaxFlow();
    vector<bool> vizSource = gr.viz;

    swap(gr.source, gr.dest);
    gr.BFSReverse();
    vector<bool> vizDest = gr.viz;

    vector<int> rasp;
    for(int i = 1; i <= n; ++i)
        for(auto j:gr.vecini[i])
            if(gr.cap[i][j] == gr.flux[i][j] && vizSource[i] == true && vizDest[j] == true)
                rasp.push_back(id[min(i, j)][max(i, j)]);

    ofstream out("critice.out");
    sort(rasp.begin(), rasp.end());
    out << rasp.size() << "\n";
    for(auto x:rasp)
        out << x << "\n";
    out.close();
    return 0;
}