Cod sursa(job #2680320)

Utilizator stanciucalinStanciu Calin stanciucalin Data 3 decembrie 2020 11:45:07
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.29 kb
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <queue>
using namespace std;

ifstream f("maxflow.in");
ofstream g("maxflow.out");

const int INF = 1000000000;

int n, m;
unordered_map <int, int> * lv; /// retin lista de vecini cu map, pentru ca nu ma intereseaza ordinea vecinilor
                               /// ci mai degraba usurinta cu care scot si adaug o muchie

int max_flow;

bool BFS(int t[]){
    /*
    cout << "lista de vecini curenta:\n";
    for(int i = 1; i <= n; i++){

        for(auto & next : lv[i]){

            cout << next.first << " " << next.second << ", ";
        }
        cout << '\n';
    }
    cout << "parcurgere curenta: ";
    */
    bool * viz = new bool [n + 1];

    t[1] = 0;

    for(int i = 1; i <= n; i++)
        viz[i] = 0;

    viz[1] = 1;

    queue <int> q;
    q.push(1);

    while(!q.empty()){

        int current_node = q.front();
        q.pop();
        //cout << current_node << " ";
        for(auto & next : lv[current_node]){

            if(next.first == n){

                t[n] = current_node;

                return 0;
            }
            else if(!viz[next.first]){

                t[next.first] = current_node;
                viz[next.first] = 1;

                q.push(next.first);
            }
        }
    }

    return 1;
}

void Edmonds_Karp(){

    /// s -> nodul 1
    /// t -> nodul n

    bool path_not_found;

    int * t = new int [n + 1];

    int k = 0;

    do{k += 1;

        path_not_found = BFS(t);

        if(!path_not_found){

            /// prima iteratie prin vectorul de tati, pentru a determina muchia de capacitate minima

            int min_capacity = INF;
            //cout << " current_capacity pe tati: ";
            int node = n;
            while(t[node]){

                int current_capacity = lv[t[node]][node];
                //cout << current_capacity << " ";
                if(current_capacity < min_capacity)
                    min_capacity = current_capacity;

                node = t[node];
            }

            max_flow += min_capacity;
            //cout << " min_capacity: " << min_capacity;
            /// a doua iteratie pentru a modifica graful rezidual
            //cout << " | parcurgere tati: ";
            node = n;
            while(t[node]){
                //cout << t[node] << " ";
                int current_capacity = lv[t[node]][node];

                if(current_capacity == min_capacity){

                    lv[t[node]].erase(node);
                }
                else
                    lv[t[node]][node] -= min_capacity;

                if(lv[node].find(t[node]) != lv[node].end()){

                    lv[node][t[node]] += min_capacity;
                }
                else
                    lv[node][t[node]] = min_capacity;

                node = t[node];
            }

        }
        //cout << " max_flow: " << max_flow << '\n';
    }
    while(!path_not_found);
}

int main(){

    f >> n >> m;

    lv = new unordered_map <int, int> [n + 1];

    int x, y, c;
    for(int i = 0; i < m; i++){

        f >> x >> y >> c;

        lv[x][y] = c;
    }

    Edmonds_Karp();

    g << max_flow;

    return 0;
}