Cod sursa(job #2746650)

Utilizator YouDontNeedMyNameJurcut Paul YouDontNeedMyName Data 28 aprilie 2021 11:22:03
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.61 kb
#include <bits/stdc++.h>
#define inf 1000000009
using namespace std;

class Edge{
public:
    Edge(): dest{0}, flow{0}, capacity{0}, rev_edge{0} {}
    Edge(int d, int c, int r): dest{d}, flow{0}, capacity{c}, rev_edge{r} {}
    int dest;
    int flow;
    int capacity;
    int rev_edge;
};

class Dinic{
public:
    vector<vector<Edge> > adj;
    vector<int> level;
    vector<int> ptr;

    Dinic(int nodes){
        adj.resize(nodes);
        level.resize(nodes);
        ptr.resize(nodes);
    }
    void add_edge(int src, int dest, int cap, bool directed){
        adj[src].push_back(Edge(dest, cap, adj[dest].size()));
        if(directed){
            adj[dest].push_back(Edge(src, 0, adj[src].size()-1));
        }
        else{
            adj[dest].push_back(Edge(src, cap, adj[src].size()-1));
        }
    }
    bool bfs(int s, int t){
        fill(level.begin(), level.end(), -1);
        fill(ptr.begin(), ptr.end(), 0);
        queue<int> q;
        q.push(s);
        level[s] = 0;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(auto &edge: adj[u]){
                int v = edge.dest;
                if(level[v] == -1 && edge.capacity > edge.flow){
                    level[v] = level[u]+1;
                    q.push(v);
                }
            }
        }
        return level[t] != -1;
    }
    int sendFlow(int u, int t, int flow){
        if(u == t){
            return flow;
        }
        for(; ptr[u] < adj[u].size(); ptr[u]++){
            Edge &e = adj[u][ptr[u]];
            if(level[e.dest] == level[u]+1 && e.capacity > e.flow){
                int curr_flow = min(flow, e.capacity-e.flow);
                int temp_flow = sendFlow(e.dest, t, curr_flow);
                if(temp_flow > 0){
                    // add flow to the edge
                    e.flow += temp_flow;
                    // subtract flow from reverse edge
                    adj[e.dest][e.rev_edge].flow -= temp_flow;
                    return temp_flow;
                }
            }
        }
        return 0;
    }
    int max_flow(int s, int t){
        if(s == t) return -1;
        int total = 0;
        while(bfs(s, t)){
            while(int flow = sendFlow(s,t,inf)){
                total += flow;
            }
        }
        return total;
    }
};

int main(){
    ifstream in("maxflow.in");
    ofstream out("maxflow.out");
    int n,m;
    in >> n >> m;
    Dinic graph(n+1);
    for(int i=0; i<m; i++){
        int x, y, c;
        in >> x >> y >> c;
        graph.add_edge(x,y,c,true);
    }
    out << graph.max_flow(1, n) << '\n';
    in.close();
    out.close();
    return 0;
}