Cod sursa(job #3129312)

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

using namespace std;

struct Edge {
    int v, flow, C, rev;
};

class Graph {
    int V;
    vector<int> excess, height;
    vector<vector<Edge>> adj;
public:
    Graph(int V);
    void addEdge(int u, int v, int C);
    void push(Edge &e, int u);
    void relabel(int u);
    void initializePreflow(int s);
    int overFlowVertex(vector<int>& excess, int s, int t);
    int getMaxFlow(int s, int t);
};

Graph::Graph(int V) {
    this->V = V;
    adj.resize(V);
    excess.resize(V);
    height.resize(V);
}

void Graph::addEdge(int u, int v, int C) {
    Edge a{v, 0, C, (int)adj[v].size()};
    Edge b{u, 0, 0, (int)adj[u].size()};
    adj[u].push_back(a);
    adj[v].push_back(b);
}

void Graph::push(Edge &e, int u) {
    int flow = min(excess[u], e.C - e.flow);
    e.flow += flow;
    adj[e.v][e.rev].flow -= flow;
    excess[e.v] += flow;
    excess[u] -= flow;
}

void Graph::relabel(int u) {
    int mh = INT_MAX;
    for(auto &e : adj[u]) {
        if(e.flow < e.C) {
            mh = min(mh, height[e.v]);
            height[u] = mh + 1;
        }
    }
}

void Graph::initializePreflow(int s) {
    height[s] = V;
    excess[s] = INT_MAX;
    for(auto &e : adj[s]) {
        push(e, s);
    }
}

int Graph::overFlowVertex(vector<int>& excess, int s, int t) {
    for(int i = 0; i < V; i++) {
        if(i != s && i != t && excess[i] > 0) {
            return i;
        }
    }
    return -1;
}

int Graph::getMaxFlow(int s, int t) {
    initializePreflow(s);
    int u = overFlowVertex(excess, s, t);
    while(u != -1) {
        bool pushed = false;
        for(auto &e : adj[u]) {
            if(e.flow < e.C && height[u] == height[e.v] + 1) {
                push(e, u);
                pushed = true;
                break;
            }
        }
        if(!pushed) {
            relabel(u);
        }
        u = overFlowVertex(excess, s, t);
    }
    return excess[t];
}


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.addEdge(x, y, z);
    }

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