Cod sursa(job #2886587)

Utilizator buzu.tudor67Tudor Buzu buzu.tudor67 Data 7 aprilie 2022 21:48:00
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.13 kb
#include <bits/stdc++.h>
using namespace std;

class Edge{
public:
    int from;
    int to;
    int capacity;
    int flow;
    Edge* reverseEdge;

    Edge(int from, int to, int capacity, int flow = 0, Edge* reverseEdge = NULL):
         from(from), to(to), capacity(capacity), flow(flow), reverseEdge(reverseEdge){}

    int getRemainingCapacity() const{
        return capacity - flow;
    }
};

class Graph{
public:
    const int N;
    vector<vector<Edge*>> edges;

public:
    Graph(const int& N): N(N){
        edges.resize(N);
    }

    void addEdge(int from, int to, int capacity){
        Edge* e1 = new Edge(from, to, capacity);
        Edge* e2 = new Edge(to, from, 0);
        e1->reverseEdge = e2;
        e2->reverseEdge = e1;
        edges[from].push_back(e1);
        edges[to].push_back(e2);
    }

    int computeMaxCapacity() const{
        int maxCapacity = 0;
        for(int node = 0; node < N; ++node){
            for(Edge* e: edges[node]){
                maxCapacity = max(maxCapacity, e->capacity);
            }
        }
        return maxCapacity;
    }
};

class FordFulkerson{
private:
    const Graph& G;
    const int N;
    const int SRC;
    const int DEST;
    vector<int> visIdOf;
    int visId;

    int augmentingPath(int node, int minDelta, const int& CAPACITY_THRESHOLD){
        if(visIdOf[node] == visId){
            return 0;
        }
        
        visIdOf[node] = visId;
        
        if(node == DEST){
            return minDelta;
        }

        for(Edge* e: G.edges[node]){
            if(e->getRemainingCapacity() > 0){
                int delta = augmentingPath(e->to, min(minDelta, e->getRemainingCapacity()), CAPACITY_THRESHOLD);
                if(delta >= CAPACITY_THRESHOLD){
                    e->flow += delta;
                    e->reverseEdge->flow -= delta;
                    return delta;
                }
            }
        }

        return 0;
    }

public:
    FordFulkerson(const Graph& G, const int& SRC, const int& DEST):
                  G(G), N(G.N), SRC(SRC), DEST(DEST){
    }

    int computeMaxFlow(){
        visIdOf.resize(N);
        visId = 0;

        int maxFlow = 0;
        int maxCapacity = G.computeMaxCapacity();
        int capacityThreshold = 1;
        while(capacityThreshold < maxCapacity){
            capacityThreshold *= 2;
        }

        while(capacityThreshold > 0){
            bool containsAugmentingPath = true;
            while(containsAugmentingPath){
                visId += 1;
                int delta = augmentingPath(SRC, INT_MAX, capacityThreshold);
                if(delta > 0){
                    maxFlow += delta;
                }else{
                    containsAugmentingPath = false;
                }
            }
            capacityThreshold /= 2;
        }

        return maxFlow;
    }
};

int main(){
    ifstream cin("maxflow.in");
    ofstream cout("maxflow.out");

    int N, M;
    cin >> N >> M;

    Graph G(N);
    int x, y, c;
    for(int i = 0; i < M; ++i){
        cin >> x >> y >> c;
        G.addEdge(x - 1, y - 1, c);
    }

    cout << FordFulkerson(G, 0, N - 1).computeMaxFlow();

    cin.close();
    cout.close();
    return 0;
}