Cod sursa(job #2831983)

Utilizator realmeabefir2huja petru realmeabefir2 Data 12 ianuarie 2022 16:51:28
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.7 kb
#include <iostream>
#include <bits/stdc++.h>

#define maxFlow  1e9

using namespace std;

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

int n, m;
int s, f;
vector<int> la[1001];
int fluxLeft[1001][1001];
int parent[1001];
int flux = 0;

struct hash_pair {
    template <class T1, class T2>
    size_t operator()(const pair<T1, T2>& p) const
    {
        auto hash1 = hash<T1>{}(p.first);
        auto hash2 = hash<T2>{}(p.second);
        return hash1 ^ hash2;
    }
};

int insideFirstComp[1001];
unordered_map<pair<int, int>, int, hash_pair> map_tunel;

void getPath()
{
    memset(parent, 0, sizeof(parent));
    vector<int> q;
    parent[s] = -1;
    q.push_back(s);

    for (int i = 0; i < q.size() ; i++)
    {
        if (q[i] == n)
        {
            continue;
        }
        for (auto to: la[q[i]])
        {
            if (fluxLeft[q[i]][to] <= 0 || parent[to] != 0)
                continue;

            parent[to] = q[i];
            q.push_back(to);
        }
    }
}

int main()
{
    in >> n >> m;
    s = 1; f = n;
    for (int i = 1; i <= m ; ++i)
    {
        int x,y,c;
        in >> x >> y >> c;
        la[x].push_back(y);
        la[y].push_back(x);

        fluxLeft[x][y] = c;
        fluxLeft[y][x] = c;

        map_tunel[{x,y}] = i;
        map_tunel[{y,x}] = i;
    }

    getPath();
    while (parent[f] != 0)
    {
        for (int i = -1; i < (int)la[f].size(); i++)
        {
            if (i != -1)
            {
                parent[f] = la[f][i];
            }

            int minn = maxFlow;
            int nod = f;
            while (parent[nod] != -1)
            {
                if (fluxLeft[parent[nod]][nod] < minn)
                    minn = fluxLeft[parent[nod]][nod];
                if (minn <= 0)
                    break;
                nod = parent[nod];
            }

            if (minn <= 0)
                continue;

            flux += minn;
            nod = f;
            while (parent[nod] != -1)
            {
                fluxLeft[parent[nod]][nod] -= minn;
                fluxLeft[nod][parent[nod]] += minn;
                nod = parent[nod];
            }
        }

        getPath();
    }

    // gasesc nodurile care se afla in prima componenta
    memset(parent, 0, sizeof(parent));
    parent[1] = -1;
    queue<int> q;
    q.push(1);
    insideFirstComp[1] = 1;
    while (q.size())
    {
        int from = q.front();
        for (auto& to: la[from])
        {
            if (fluxLeft[from][to] <= 0 || parent[to] != 0)
                continue;
            parent[to] = from;
            insideFirstComp[to] = 1;
            q.push(to);
        }
        q.pop();
    }

    vector<int> sol;

    memset(parent, 0, sizeof(parent));
    parent[1] = -1;
    q.push(1);
    while (q.size())
    {
        int from = q.front();
        for (auto& to: la[from])
        {
            if (fluxLeft[from][to] <= 0 || parent[to] != 0)
            {
                if (!insideFirstComp[to])
                {
                    sol.push_back(map_tunel[{from, to}]);
                    // cout << from << ' ' << to << '\n';
                    // parent[to] = from;
                }
                continue;
            }
            parent[to] = from;
            q.push(to);
        }
        q.pop();
    }

    sort(sol.begin(), sol.end());
    out << sol.size() << '\n';
    for (int poz: sol)
        out << poz << '\n';

    // out << flux;

    return 0;
}

/*
6 8
1 2 10
1 3 8
2 3 2
2 4 5
3 5 10
5 4 8
4 6 7
5 6 10
// 15
*/

/*
6 7
1 2 6
1 3 8
2 4 5
3 5 4
2 5 3
4 6 7
5 6 5
// 10
*/