Cod sursa(job #2957076)

Utilizator SteanfaDiaconu Stefan Steanfa Data 21 decembrie 2022 17:23:26
Problema Taramul Nicaieri Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.74 kb
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <utility>
#include <queue>

class Flux
{
private:
    int _n;
    std::vector<std::vector<int>> _adiac;
    std::vector<std::vector<int>> _capaci;
    void dfs(int nod, std::vector<int> &seen) const
    {
        seen[nod] = 1;
        for (auto &&nn : _adiac[nod])
        {
            if (!seen[nn] and _capaci[nod][nn] > 0)
            {
                dfs(nn, seen);
            }
        }
    }

public:
    std::vector<std::vector<int>> getCapacity()const  { return _capaci; }
    int taieturaMinima() const // O(m * n)
    {
        std::vector<int> seen(_adiac.size(), 0);
        dfs(1, seen);

        int taietura_minma_cost = 0;

        for (size_t i = 1; i <= _n; i++)
        {

            if (seen[i])
            {
                for (auto &&cop : _adiac[i])
                {
                    if (!seen[cop])
                    {
                        taietura_minma_cost += _capaci[cop][i];
                    }
                }
            }
        }
        return taietura_minma_cost;
    }

    int getMaxFlux()
    {

        int total = 0;
        while (1)
        {

            int fluxTotal = 0;
            std::queue<int> q;
            std::vector<int> generator(_adiac.size(), 0);
            std::vector<bool> mark(_adiac.size(), 0);
            q.push(1);
            mark[1] = true;

            while (!q.empty())
            {
                int nod = q.front();
                q.pop();
                if (nod == this->_n) // aici o sa vedem din toate caile formate daca putem adauga flux ca sa nu refacem bfs-ul iar si iar;
                {

                    for (auto &&contestant : this->_adiac[nod])
                    {
                        if (this->_capaci[contestant][nod] == 0 or mark[contestant] == 0)
                            continue;

                        int fluxx = this->_capaci[contestant][nod];
                        int checkFlux = contestant;
                        while (checkFlux != 1)
                        {
                            fluxx = std::min(fluxx, this->_capaci[generator[checkFlux]][checkFlux]);
                            checkFlux = generator[checkFlux];
                        }

                        fluxTotal += fluxx;
                        this->_capaci[nod][contestant] += fluxx;
                        this->_capaci[contestant][nod] -= fluxx;
                        checkFlux = contestant;
                        while (checkFlux != 1)
                        {
                            this->_capaci[checkFlux][generator[checkFlux]] += fluxx;
                            this->_capaci[generator[checkFlux]][checkFlux] -= fluxx;
                            checkFlux = generator[checkFlux];
                        }
                    }
                    break;
                }

                for (auto &&vecin : this->_adiac[nod])
                {
                    if (this->_capaci[nod][vecin] != 0 and mark[vecin] == 0)
                    {
                        mark[vecin] = 1;
                        generator[vecin] = nod;
                        q.push(vecin);
                    }
                }
            }

            if (fluxTotal == 0)
            {
                break;
            }

            total += fluxTotal;
        }
        return total;
    }
    Flux(const std::vector<std::vector<int>> &, std::vector<std::vector<int>>, const int &);
    ~Flux() = default;
};

Flux::Flux(const std::vector<std::vector<int>> &v, std::vector<std::vector<int>> cap, const int &n) : _n{n}, _adiac{std::move(v)}, _capaci{std::move(cap)}
{
}

const short magic = 203;
std::vector<std::vector<int>> v(magic);
std::vector<std::vector<int>> capaci(magic, std::vector<int>(magic));
int main()
{
    std::ifstream cin("harta.in");
    std::ofstream cout("harta.out");

    short n;
    cin >> n;
    int x, y;

    for (size_t i = 2; i <= n + 1; i++)
    {
        cin >> x >> y;
        v[1].push_back(i);
        v[i].push_back(1);
        capaci[1][i] = x;

        v[2 * n + 2].push_back(n + i);
        v[n + i].push_back(2 * n + 2);
        capaci[n + i][2 * n + 2] = y;
    }

    for (size_t i = 2; i <= n + 1; i++)
        for (size_t j = 2; j <= n + 1; j++)
        {
            if (i != j)
            {
                v[i].push_back(j + n);
                v[j + n].push_back(i);
                capaci[i][j + n] = 1;
            }
        }

    Flux asd{v, capaci, n * 2 + 2};
    cout << asd.getMaxFlux() << "\n";

    capaci = asd.getCapacity();

    for (size_t i = 2; i <= n + 1; i++)
        for (size_t j = 2; j <= n + 1; j++)
        {
            if (i != j and capaci[i][j + n] == 0)
            {
                cout << i - 1 << ' ' << j - 1 << "\n";
            }
        }
}