Cod sursa(job #2960424)

Utilizator pasare.franci@yahoo.comPasare Francisca [email protected] Data 4 ianuarie 2023 13:12:06
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.82 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream f("maxflow.in");
ofstream g("maxflow.out");

int n,m, sursa;

vector<vector <int>> adiacenta;
vector<bool> visited;
vector<int> parent;
queue<int> q;
vector<vector<int>> rezidual;


int bfs (int node) {
    fill(visited.begin(), visited.end(), 0);
    visited[node] = 1;
    //punem in coada vf de start
    q.push(node);

    while (!q.empty()) {
        int nod_curent = q.front();
        q.pop();
        //mergem prin vecinii varfului scos din coada
        for (auto i:adiacenta[nod_curent]) {
            //daca nu a mai fost vizitata si daca are capacitatea de flux si daca nu e varful destinatie il puntem in stiva
            if (!visited[i] && i!=n && rezidual[nod_curent][i]>0) {
                visited[i] = 1;
                q.push(i);
                parent[i] = nod_curent;
            }
        }
    }

    int max_flow_possible = 0;
    //daca varfurile vecine destinatiei au fost vizitate in timpul bfs ului
    for (auto i : adiacenta[n]) {
        if (!visited[i])
            continue;
        int flow_min = rezidual[i][n];
        int aux = i;
        //aflam fluxul minim care poate fi transportat
        while (aux != 1) {
            flow_min = min(flow_min, rezidual[parent[aux]][aux]);
            aux = parent[aux];
        }

        //updatam graful rezidual , mai intai muchia vecina cu nodul destinatie dupa care ,
        // folosing vectorul de tati , restul nodurilor pana la sursa
        rezidual[n][i] += flow_min;
        rezidual[i][n] -= flow_min;

        aux = i;

        while (aux != 1) {
            rezidual[aux][parent[aux]] += flow_min;
            rezidual[parent[aux]][aux] -= flow_min;
            aux = parent[aux];
        }
        //adaugam in rezultat fluxul minim
        max_flow_possible += flow_min;
    }

    return max_flow_possible;
}

int get_max_flow(){
    int total_max_flow = 0;
    //luam primul augmenting path
    int augment_path = bfs(sursa);
    //cat timp avem augmenting path
    while (augment_path) {
        //adaugam la rezultat ce a returnat functia
        total_max_flow += augment_path;
        //apelam iar functia pentru aflarea unui augmenting path
        augment_path = bfs(sursa);
    }

    return total_max_flow;
}

int main ()
{
    f>>n>> m;
    adiacenta.resize(n+1);
    visited.resize(n+1,0);
    rezidual.resize(n+1, vector<int>(n+1, 0));
    parent.resize(n+1, -1);
    sursa = 1;
    for (int i=0; i<m; i++) {
        //citim datele si punem in lista de adiacenta si in graful rezidual
        int x,y,z;
        f>> x >> y >> z;
        adiacenta[x].push_back(y);
        adiacenta[y].push_back(x);
        rezidual[x][y] += z;
    }
    g<<get_max_flow();
    return 0;
}