Cod sursa(job #2954395)

Utilizator RobertuRobert Udrea Robertu Data 14 decembrie 2022 10:05:48
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.2 kb
#include <bits/stdc++.h>
#define dim 1010
#define inf INT_MAX
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");

/*
    Idee: a) Pentru flux maxim am folosit ideea cu graf rezidual, in care pentru fiecare
        muchie avem si muchia inversa dar cu cost 0, gasim un drum cu muchii nesaturate(cost nenul)
        de la sursa la destinatie, si apoi scadem fluxul minim din muchiile pe care am venit si il adunam
        pe inversele lor. Repetam asta pana cand nu mai gasim niciun drum. Avem si optimizarea nebuna in
        care dupa ce gasim un drum, ne intoarcem sa modificam toate drumurile care mai exista.
        Graful rezidual l amm integrat in graful original, dupa explicatiile lui tushar:
        https://www.youtube.com/watch?v=GiN3jRdgxU4&t=366s&ab_channel=TusharRoy-CodingMadeSimple
*/

long long maxFlow = 0;
int tata[dim], a[dim][dim], n, m, x, y, z, nod, flow;
bool viz[dim];
queue< int > coada; 

bool bfs() {
    while(!coada.empty()) {
        coada.pop();
    }
    memset(tata, 0, sizeof(tata));
    memset(viz, false, sizeof(viz));

    coada.push(1);
    viz[1] = true;
    while(!coada.empty()) {
        int front = coada.front();
        coada.pop();

        if(front == n) {
            return true;
        }

        for(int i = 1; i <= n; i++) {
            if( !viz[i] &&  a[front][i] > 0) {
                coada.push(i);
                viz[i] = true;
                tata[i] = front;
            }
        }
    }
    return false;
}

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

    for(int i = 0; i < m; i++) {
        fin >> x >> y >> z;
        a[x][y] = z;
    }

    while(bfs()) {
        for(int i = 1; i < n; i++) {
            if( viz[i] && a[i][n] > 0 ) {
                flow = inf;
                tata[n] = i;
                for(nod = n; tata[nod] > 0; nod = tata[nod]) {
                    flow = min(flow, a[ tata[nod] ][nod]);
                }

                if(flow == 0) continue;

                for(nod = n; tata[nod] > 0; nod = tata[nod]) {
                    a[ tata[nod] ][nod] -= flow;
                    a[nod][ tata[nod] ] += flow;
                }

                maxFlow += flow;
            }
        }
    }

    fout << maxFlow << '\n';

    return 0;
}