Cod sursa(job #3129313)

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

using namespace std;

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

class Graph {
    int n;
    vector<int> h, e, cur;
    vector<vector<Edge>> g;

    void add_edge_internal(int from, int to, int cap) {
        g[from].push_back({to, (int) g[to].size(), 0, cap});
        g[to].push_back({from, (int) g[from].size() - 1, 0, 0});
    }

    void push(Edge &edge, int u, int v) {
        int flow = min(e[u], edge.cap - edge.flow);
        edge.flow += flow;
        g[v][edge.rev].flow -= flow;
        e[u] -= flow;
        e[v] += flow;
    }

    void relabel(int u) {
        h[u] = 2e9;
        for (auto &edge : g[u]) {
            if (edge.cap - edge.flow > 0) {
                h[u] = min(h[u], h[edge.to] + 1);
            }
        }
    }

    vector<int> find_max_height_vertices(int source, int dest) {
        vector<int> max_height;
        for (int i = 0; i < n; i++) {
            if (i != source && i != dest && e[i] > 0) {
                if (!max_height.empty() && h[i] > h[max_height[0]]) {
                    max_height.clear();
                }
                if (max_height.empty() || h[i] == h[max_height[0]]) {
                    max_height.push_back(i);
                }
            }
        }
        return max_height;
    }

public:
    Graph(int n) : n(n), h(n), e(n), cur(n), g(n) {}

    void add_edge(int from, int to, int cap) {
        add_edge_internal(from, to, cap);
        add_edge_internal(to, from, 0);
    }

    int max_flow(int source, int dest) {
        h[source] = n;
        e[source] = INT_MAX;
        for (auto &edge : g[source]) {
            push(edge, source, edge.to);
        }

        while (true) {
            auto max_height = find_max_height_vertices(source, dest);
            if (max_height.empty())
                break;

            for (auto i : max_height) {
                bool pushed = false;
                for (int j = cur[i]; j < g[i].size() && e[i]; j++) {
                    auto &edge = g[i][j];
                    if (edge.cap - edge.flow > 0 && h[i] == h[edge.to] + 1) {
                        push(edge, i, edge.to);
                        pushed = true;
                    }
                    cur[i] = j;
                }

                if (!pushed) {
                    relabel(i);
                    cur[i] = 0;
                }
            }
        }

        int max_flow = 0;
        for (auto &edge : g[source])
            max_flow += edge.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;
    Graph g(n);
    for(int i = 1; i <= m; i ++) {
        cin >> x >> y >> z;
        x--;
        y--;

        g.add_edge(x, y, z);
    }

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