Cod sursa(job #3129309)

Utilizator razviii237Uzum Razvan razviii237 Data 13 mai 2023 21:53:56
Problema Flux maxim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
// CHAT GPT 4
#include <iostream>
#include <cstdio>
#include <vector>
#include <limits>
#include <queue>

using namespace std;

const int INF = numeric_limits<int>::max();

struct Edge {
    int to, capacity, flow, rev;
};

void add_edge(vector<vector<Edge>>& graph, int from, int to, int capacity) {
    graph[from].push_back({to, capacity, 0, (int)graph[to].size()});
    graph[to].push_back({from, 0, 0, (int)graph[from].size() - 1});
}

void push(vector<vector<Edge>>& graph, vector<int>& excess, int u, Edge& e) {
    int flow = min(excess[u], e.capacity - e.flow);
    e.flow += flow;
    graph[e.to][e.rev].flow -= flow;
    excess[e.to] += flow;
    excess[u] -= flow;
}

void relabel(vector<vector<Edge>>& graph, vector<int>& height, int u) {
    int min_height = INF;
    for (const auto& e : graph[u]) {
        if (e.capacity > e.flow) {
            min_height = min(min_height, height[e.to]);
        }
    }
    if (min_height < INF) {
        height[u] = min_height + 1;
    }
}

void discharge(vector<vector<Edge>>& graph, vector<int>& excess, vector<int>& height, vector<int>& current, int u) {
    while (excess[u] > 0) {
        if (current[u] == graph[u].size()) {
            relabel(graph, height, u);
            current[u] = 0;
        } else {
            Edge& e = graph[u][current[u]];
            if (e.capacity > e.flow && height[u] > height[e.to]) {
                push(graph, excess, u, e);
            } else {
                current[u]++;
            }
        }
    }
}

int max_flow(vector<vector<Edge>>& graph, int source, int sink) {
    int V = graph.size();
    vector<int> excess(V, 0), height(V, 0), current(V, 0);

    height[source] = V;
    excess[source] = INF;
    for (auto& e : graph[source]) {
        push(graph, excess, source, e);
    }

    queue<int> active;
    for (int u = 0; u < V; ++u) {
        if (u != source && u != sink && excess[u] > 0) {
            active.push(u);
        }
    }

    while (!active.empty()) {
        int u = active.front();
        active.pop();
        discharge(graph, excess, height, current, u);
        if (excess[u] > 0) {
            active.push(u);
        }
    }

    int max_flow = 0;
    for (const auto& e : graph[source]) {
        max_flow += e.flow;
    }
    return max_flow;
}

int main() {
    int n, m, x, y, z;
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);
    cin >> n >> m;
    vector <vector<Edge> > v(n);
    for(int i = 1; i <= m; i ++) {
        cin >> x >> y >> z;
        x--;
        y--;

        add_edge(v, x, y, z);
    }

    cout << max_flow(v, 0, n-1) << '\n';
    return 0;
}