Cod sursa(job #2746657)

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

class Edmonds{
public:
    Edmonds(int nodes){
        father.resize(nodes);
        flow.resize(nodes);
        capacity.resize(nodes);
        for(int i=0; i<nodes; i++){
            flow[i].resize(nodes, 0);
            capacity[i].resize(nodes, 0);
        }
        adj.resize(nodes);
    }
    void add_edge(int src, int dest, int cap, bool direct){
        //if the edges are not unique, take the sum of all the edges
        if(!capacity[src][dest] && !capacity[dest][src]){
            adj[src].push_back(dest);
            adj[dest].push_back(src);
        }
        capacity[src][dest] = cap;
        if(!direct){
            capacity[dest][src] = cap;
        }
    }
    vector<int> father;
    vector<vector<int> > flow;
    vector<vector<int> > capacity;
    vector<vector<int> > adj;
    bool bfs(int s, int t){
        //set all fathers to -1 
        //create the tree
        fill(father.begin(), father.end(), -1);
        queue<int> q;
        father[s] = s;
        q.push(s);
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(auto v: adj[u]){
                if(capacity[u][v] > flow[u][v] && father[v] == -1){
                    father[v] = u;
                    q.push(v);
                }
            }
        }
        return father[t] != -1;
    }

    int max_flow(int s, int t){
        if(s == t) return -1;
        //adj has both edges x -> y; y -> x
        int total = 0;
        while(bfs(s, t)){
            for(auto u: adj[t]){
                if(father[u] == -1) continue;
                int current_flow = capacity[u][t] - flow[u][t];
                if(current_flow == 0) continue;
                for(int v = u; v != s; v = father[v]){
                    int w = father[v];
                    current_flow = min(current_flow, capacity[w][v] - flow[w][v]);
                    if(current_flow == 0) break;
                }
                if(current_flow == 0) continue;
                flow[u][t] += current_flow;
                flow[t][u] -= current_flow;
                for(int v = u; v != s; v = father[v]){
                    int w = father[v];
                    flow[w][v] += current_flow;
                    flow[v][w] -= current_flow;
                }
                total += current_flow;
            } 
        }
        return total;
    }
};

int main(){
    ifstream in("maxflow.in");
    ofstream out("maxflow.out");
    int n,m;
    in >> n >> m;
    Edmonds 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;
}