Cod sursa(job #3309069)

Utilizator alesiodemiriAlesio Demiri alesiodemiri Data 31 august 2025 18:17:04
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.31 kb
#include <iostream>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <iomanip>
#include <climits>

using namespace std;

struct Edge {
    int end;
    int flow;
    int capacity;

    Edge(int end, int flow, int capacity): end(end), flow(flow), capacity(capacity){}
};

#define ll long long

int n,m;
vector<vector<Edge>> graph;
vector<int> degIn;
vector<int> degOut;
int source = 0;
int drain = 0;

void ReadData() {
    cin >> n >> m;
    degIn.resize(n, 0);
    degOut.resize(n, 0);

    graph.resize(n, vector<Edge>());
    int start, end, capacity;
    for(int i = 0; i < m; ++i){
        cin >> start >> end >> capacity;
        start--;end--;
        graph[start].push_back(Edge(end, 0, capacity));
        graph[end].push_back(Edge(start, 0, 0));
        degOut[start]++;
        degIn[end]++;
    }
}

vector<int> bfs(int a, int b){
    unordered_set<int> visited;
    queue<int> q;
    q.push(a);
    visited.insert(a);
    vector<int> result;

    while (!q.empty()){
        int node = q.front();
        result.push_back(node);
        q.pop();

        for (Edge edge: graph[node]){
            int neighbour = edge.end;
            if (edge.flow == edge.capacity) continue;

            if(neighbour == b){
                result.push_back(neighbour);
                return result;
            }

            if (visited.find(neighbour) == visited.end()){
                q.push(neighbour);
                visited.insert(neighbour);
            }  
        }
    }
    return result;
}

void Solve() {
    for(int i = 0; i < n; i++){
        if (degIn[i] == 0) source = i;
        if (degOut[i] == 0) drain = i;  
    } 

    while(true){
        vector<int> path = bfs(source, drain);
        if (path[path.size() - 1] != drain){
            break;
        }
        else{

            int minFlow = INT_MAX;
            for(int i = 0; i < path.size() - 1; i++){
                int start = path[i];
                int end = path[i+1];

                for (Edge& e: graph[start]){
                    if (e.end == end && e.flow < e.capacity){
                        minFlow = min(minFlow, e.capacity - e.flow);
                    }
                    
                }
                
            }
            
            for(int i = 0; i < path.size() - 1; i++){
                int start = path[i];
                int end = path[i+1];

                for (Edge& e: graph[start]){
                    if (e.end == end){
                        e.flow += minFlow;
                        break;
                    }  
                }

                for (Edge& e: graph[end]){
                    if (e.end == start){
                        e.flow -= minFlow;
                        break;
                    }  
                }
            }
        }    
    } 

    int result = 0;
    for(Edge edge: graph[0]){
        result+= edge.flow;
    }

    cout << result << "\n";
    

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);

    int t = 1;
    // cin >> t; // Uncomment for multiple test cases
    while (t--) {
        ReadData();
        Solve();   
    }
    return 0;
}