Cod sursa(job #2970058)

Utilizator ArthurelVilceanu Razvan-Arthur Arthurel Data 24 ianuarie 2023 10:55:15
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.05 kb
#include <bits/stdc++.h>
using namespace std;


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

// Se foloseste algoritmul Ford Fulkerson - Edmonds Karp

// Se Foloseste un BFS pentru a gasi un drum de la nodul start la destinatie care sa treaca prin muchii cu flux diferit de 0
// Se foloseste un vector de noduri vizitate si un vector de parinti pentru a reconstrui drumul
// Dupa fiecare bfs se ia flow-ul minim, se scade din toate muchiile drumului si se adauga la flow-ul maxim


int capacity[1001][1001],n,m,flow,max_flow;
vector<int> visited,parent;
vector<vector<int>> adj_list;
vector<pair<int,int>>taietura;

bool bfs()
{
    // Se initializeaza vectorul de parinti si cel de vizitati cu 0

    fill(visited.begin(), visited.end(), 0);
    fill(parent.begin(), parent.end(), 0);

    visited[1] = 1;
    parent[1] = 1;
    queue<int> q;
    q.push(1);


    while(!q.empty())
    {
        int nod = q.front();

        q.pop();

        // Daca s-a gasit destinatia
        if(nod == n)
            return true;
        // Se cauta prin vecinii nodului un nod nevizitat si cu flow-ul mai mare decat 0
        for(int i=0; i<adj_list[nod].size(); i++)
        {
            if(!visited[adj_list[nod][i]] && capacity[nod][adj_list[nod][i]] > 0)
            {
                q.push(adj_list[nod][i]);
                parent[adj_list[nod][i]] = nod;
                visited[adj_list[nod][i]] = 1;
            }
            // else if (parent[adj_list[nod][i]]==0 && capacity[nod][adj_list[nod][i]==0)
            //      taietura.push_back( {nod, adj_list[nod][i]})
        }
    }

    return false;


}

int main()
{
    int a,b,c;
    f>>n>>m;
    visited.resize(n+2, 0);
    parent.resize(n+2, 0);
    adj_list.resize(n+2, {});

    // Citire date

    for(int i=1; i<=m; i++)
    {
        f>>b>>c>>a;
        adj_list[b].push_back(c);
        adj_list[c].push_back(b);
        capacity[b][c] = a;
    }

    int result = bfs();


    // Se face bfs pana nu mai exista drum intre nod start si nod final doar prin muchii cu flow>0
    while(result)
    {
        for(int i=0; i<adj_list[n].size(); i++)
        {
            if(visited[adj_list[n][i]])
            {
                parent[n] = adj_list[n][i];
                flow = INT_MAX;

                // Se calculeaza cel mai mic flow din drum
                for(int j=n; j!=1; j=parent[j])
                {
                    flow=min(flow, capacity[parent[j]][j]);
                }
                if(flow != 0)
                {
                    // Se reduce flow-ul minim din toate muchiile din drum
                    for(int j=n; j!=1; j=parent[j])
                    {
                        capacity[parent[j]][j] -= flow;
                        capacity[j][parent[j]] += flow;
                    }
                    // Se aduna flow-ul minim din drum la flow-ul total
                    max_flow += flow;
                }
            }
        }
        result = bfs();
    }
    g<<max_flow;
    return 0;
}