Cod sursa(job #2960674)

Utilizator ctimburCristina T ctimbur Data 4 ianuarie 2023 20:07:12
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.53 kb
#pragma GCC optimize "O3"
#include <algorithm>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

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

int n, x, y, g[1001][1001];
queue <int> q;
bool visited[1001];
int parinte[1001];

// Intoarce un boolean care arata daca a gasit sau nu macar un drum de ameliorare.
bool bfs() {
    while (q.empty() == false)
        q.pop();

    for (int i = 0; i <= n; i++) {
        parinte[i] = 0;
        visited[i] = false;
    }
    int sursa = 1;
    q.push(sursa);
    visited[sursa] = true;

    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        if (nod == n)
            // Am ajuns la destinatie, deci am gasit un drum.
            return true;
        for (int i = 1; i <= n; i++)
            if (!visited[i] && g[nod][i] > 0) {
                q.push(i);
                parinte[i] = nod;
                visited[i] = true;
            }
    }
    return false;
}

int flux() {
    int maxFlow = 0;
    // Atata timp cat mai exista drumuri de ameliorare, inseamna ca mai putem adauga flux.
    while (bfs()) {
        for (int i = 1; i < n; i++) {
            if (g[i][n] > 0 && visited[i]) {
                int frunza = i;
                vector <int> drum;
                drum.push_back(n);
                drum.push_back(frunza);

                int nod = parinte[frunza];

                if (nod == 1)
                    drum.push_back(nod);
                else {
                    while (nod != 1) {
                        drum.push_back(nod);
                        nod = parinte[nod];
                    }
                    drum.push_back(1);
                }
                // Fac reverse la vector, pentru ca ordinea elementelor sa fie de la nodul de start spre destinatie.
                reverse(drum.begin(), drum.end());

                int minCap = 2e9;
                for (int i = 0; i < drum.size() - 1; i++)
                    minCap = min(minCap, g[drum[i]][drum[i + 1]]);

                maxFlow += minCap;

                for (int i = 0; i < drum.size() - 1; i++) {
                    // Scad capacitatea minima din muchiile drumului.
                    g[drum[i]][drum[i+1]] -= minCap;
                    // Adaug la muchiile inverse.
                    g[drum[i+1]][drum[i]] += minCap;
                }
            }
        }
    }
    return maxFlow;
}

int main() {
    int cap, m;
    fin >> n >> m;
    for (int i = 0; i < m; i++) {
        fin >> x >> y >> cap;
        g[x][y] = cap;
    }
    fout << flux();
    return 0;
}