Cod sursa(job #2961394)

Utilizator cyg_vladioanBirsan Vlad cyg_vladioan Data 6 ianuarie 2023 14:03:15
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.62 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <climits>

const int INF = INT_MAX;

struct Edge{
    int x, y, cap_flow;
    Edge(int x = 0, int y = 0, int cap_flow = 0): x(x), y(y), cap_flow(cap_flow) {}
};


class MaxFlow{
private:
    int n, s, d;
    std::vector<Edge> edges;
    std::vector<std::vector<int>> G;
    std::vector<int> t;

public:
    MaxFlow(int, int, int, std::vector<std::pair <int, std::pair<int, int>>>&);
    int bfs();
    int update_flow();
    int max_flow(); 
    std::vector<std::pair<int, int>> matching(int);
};

MaxFlow::MaxFlow(int n, int s, int d, std::vector<std::pair <int, std::pair<int, int>>>& _edges): n(n), s(s), d(d){
    int i = 0;
    G = std::vector<std::vector<int>>(n);

    for(const auto& edge: _edges){
        G[edge.first].push_back(i ++);
        G[edge.second.first].push_back(i ++);
        edges.push_back({edge.first, edge.second.first, edge.second.second});
        edges.push_back({edge.second.first, edge.first, edge.second.second});
    }
}

int MaxFlow::bfs(){
    std::queue<int> q;

    t = std::vector<int> (n, -1);
    t[s] = -2;
    q.push(s);

    while(!q.empty()){
        int u = q.front();
        q.pop();
        if(u == d)
            continue;
        for(const auto& edge_id: G[u]){
            int v = edges[edge_id].y; 
            if(t[v] == -1 && edges[edge_id].cap_flow > 0){
                t[v] = edge_id;
                q.push(v);
            }
        }
    }

    return t[d] != -1;
}

int MaxFlow::update_flow(){
    int node, flow;
    flow = INF;
    
    for(node = d; t[node] != -2; node = edges[t[node]].x)
        flow = std::min(flow, edges[t[node]].cap_flow);
    
    for(node = d; t[node] != -2; node = edges[t[node]].x){
        edges[t[node]].cap_flow -= flow;
        edges[t[node] ^ 1].cap_flow += flow;
    }

    return flow;
}

int MaxFlow::max_flow(){
    int flow = 0;
    
    while(bfs()){
        for(const auto& edge_id: G[d]){
            int node = edges[edge_id].y;
            int cap_flow = edges[edge_id ^ 1].cap_flow;
            if(cap_flow == 0 || t[node] == -1)
                continue;
            t[d] = edge_id ^ 1;
            flow += update_flow();
        }
    }

    return flow;
}

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

    int n, m, x, y, z;
    std::vector<std::pair <int, std::pair<int, int>>> edges;

    scanf("%d%d", &n, &m);
    for(int i = 0; i < m; i ++){
        scanf("%d%d%d", &x, &y, &z);
        edges.push_back({x - 1, {y - 1, z}});
    }

    MaxFlow maxflow(n, 0, n - 1, edges);
    int max_flow = maxflow.max_flow();

    printf("%d\n", max_flow);

    return 0;
}