Cod sursa(job #2642948)

Utilizator stefan.popescuPopescu Stefan stefan.popescu Data 17 august 2020 19:59:22
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.09 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
ifstream in ("maxflow.in");
ofstream out("maxflow.out");
struct Dinic{
    const int oo=2e9;
    struct mc{
        int u, v, capacity, flow=0;
        mc(int uu, int vv, int capp){
            u=uu; v=vv; capacity=capp;
        }
    };
    int s, t;
    queue <int> q;
    vector <mc> muchii;
    vector <vector<int> > vecini;
    vector <int> lastPtr, bfsLevel;
    Dinic(int n, int ss, int tt){
        lastPtr.resize(n+1);
        vecini.resize(n+1);
        bfsLevel.resize(n+1);
        s=ss; t=tt;
    }
    void insert_edge(int x, int y, int cap){
        muchii.push_back(mc{x, y, cap});
        vecini[x].push_back(muchii.size()-1);
        muchii.push_back(mc{y, x, 0});
        vecini[y].push_back(muchii.size()-1);
    }
    int dfsFlow(int nodAct, int fluxAct){
        if(fluxAct==0)
            return 0;
        if(nodAct==t)
            return fluxAct;
        for(int & att=lastPtr[nodAct]; att<(int)vecini[nodAct].size(); att++){///mut efectiv pointer-ul respectiv
            int id=vecini[nodAct][att];
            int nodNext=muchii[id].v;
            if(bfsLevel[nodNext]!=bfsLevel[nodAct]+1) ///flux path-ul nu are lungimea cea mai mica de la bfs
                continue;
            if(muchii[id].capacity-muchii[id].flow<1) ///adica e saturata muchia
                continue;
            int tempFlow=dfsFlow(nodNext, min(fluxAct, muchii[id].capacity-muchii[id].flow));
            if(tempFlow==0) ///pe muchia asta n-am sanse
                continue;
            muchii[id].flow+=tempFlow;
            muchii[id^1].flow-=tempFlow;
            return tempFlow;
            ///se presupune ca muchiile consecutive in graful rezidual se inverseaza reciproc
        }
        return 0; ///in caz ca toate muchiile nu merg
    }

    bool bfsFlow(){
        fill(bfsLevel.begin(), bfsLevel.end(), -1);
        bfsLevel[s]=0;
        q.push(s);
        while(!q.empty()){

            int nodAct = q.front();
            q.pop();
            for(int id:vecini[nodAct]){
                if(muchii[id].capacity-muchii[id].flow<1)
                    continue;
                if(bfsLevel[muchii[id].v]!=-1)
                    continue;
                bfsLevel[muchii[id].v]=bfsLevel[nodAct]+1;
                q.push(muchii[id].v);
            }
        }
        return bfsLevel[t]!=-1;
    }

    long long maxFlow(){ ///sursa si scurgere
        long long ans=0;

        while(true){

            if(!bfsFlow())
                break;
            fill(lastPtr.begin(), lastPtr.end(), 0); ///ca la fiecare dfs sa am toate muchiile disponibile de la inceput (exceptie cele saturate)
            while(int moreFlow=dfsFlow(s, oo) ){
                ans+=moreFlow;
            }
        }
        return ans;
    }
};
int n, m;
int x, y, c;
int main()
{
    in>>n>>m;
    Dinic dc(n, 1, n);
    for(int i=1; i<=m; i++){
        in>>x>>y>>c;
        dc.insert_edge(x, y, c);
    }

    out<<dc.maxFlow();
    return 0;
}