Cod sursa(job #2961657)

Utilizator BojneaguBojneagu David-Alexandru Bojneagu Data 6 ianuarie 2023 20:18:39
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.2 kb
#include <bits/stdc++.h>
using namespace std;

#define MaxSize 2000
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");

int n, m, elem, nod, flux_max, flux_min, firstelem, k, capacitate[MaxSize][MaxSize], flux_curr[MaxSize][MaxSize];
vector<vector < int>> adj, reversed_adj;
vector<int> tata;
vector<bool> viz;
queue<int> que;


void flux_update()

{
    for (auto vec: reversed_adj[n])	// mergem pe reversed_adj pentru a putea merge de la destinatie la coada

        if (capacitate[vec][n] >= flux_curr[vec][n] && viz[vec] == true)
        {
            elem = n;
            tata[n] = vec;
            flux_min = INT_MAX;

            while (elem != 1)
            {
                nod = tata[elem];

                if (nod > 0)
                {
                    int ramas = capacitate[nod][elem] - flux_curr[nod][elem];
                    if (flux_min > ramas)
                        flux_min = ramas;	// stabilesc fluxul minim pe care l pot pompa, ducandu ma de la destinatie
                    // la inceput, si practic minim-ul dintre maximul fiecaruia este raspunsul.
                }
                else if (flux_min > flux_curr[elem][-nod])
                    flux_min = flux_curr[elem][-nod];

                elem = nod;
                if (elem < 0)
                    elem = -elem;
            }

            elem = n;

            while (elem != 1)
            {
                nod = tata[elem];

                if (nod > 0)

                {

                    flux_curr[nod][elem] += flux_min;
                }
                else

                    flux_curr[elem][-nod] -= flux_min;

                elem = nod;
                if (elem < 0)
                    elem = -elem;
            }

            flux_max = flux_max + flux_min;
        }
}

int BFS(int node)
{
    while (!que.empty()) que.pop();

    tata.clear();
    tata.resize(n + 1, 0);
    viz.clear();
    viz.resize(n + 1, false);

    que.push(node);
    viz[node] = true;

    while (!que.empty())
    {
        firstelem = que.front();
        que.pop();

        for (auto vec: adj[firstelem])
        {
            if (viz[vec] == false && capacitate[firstelem][vec] > flux_curr[firstelem][vec])
            {
                que.push(vec);
                viz[vec] = true;
                tata[vec] = firstelem;
                if (vec == n) return 1;	// aici actualizam lista de vizitati si tati.
            }
        }

        for (auto vec: reversed_adj[firstelem])
        {
            if (viz[vec] == false && flux_curr[vec][firstelem] > 0)
            {
                que.push(vec);
                viz[vec] = true;
                tata[vec] = -firstelem;
                if (vec == n) return 1;
            }
        }
    }

    return 0;

}


int main()
{
    fin >> n >> m;

    adj.resize(n + 1);
    reversed_adj.resize(n + 1);

    tata.resize(n + 1);
    viz.resize(n + 1);
    int cant, a, b;

    for (int i = 0; i < m; i++)
    {
        fin >> a >> b >> cant;
        adj[a].push_back(b);
        reversed_adj[b].push_back(a);
        capacitate[a][b] = cant;
        flux_curr[a][b] = 0;
    }

    flux_max = 0;

    while (BFS(1))
    {
        flux_update();
    }

    fout << flux_max;
    fin.close();
    fout.close();

}