Cod sursa(job #2684100)

Utilizator AndreiStanescuAlloys Nokito AndreiStanescu Data 12 decembrie 2020 18:49:18
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.44 kb
#include<bits/stdc++.h>
#define oo 1e18
#define ll long long
#define pii pair<int,int>
#define pil pair<int, ll>
#define mp make_pair
#define N 1024
using namespace std;

ifstream fin("maxflow.in");
ofstream fout("maxflow.out");

int n,m;


struct Dinic{
    int n,m;
    int source, sink;
    vector<vector<pii>> G;
    vector<int> lvl,start;
    vector<vector<int>> flow;
    queue<int> q;

    Dinic(int n, int m, int s, int t) : m(m), n(n), source(s), sink(t) {
        G.resize(n);
        lvl.resize(n);
        start.resize(n);
        flow.resize(n);
        for(int i=0;i<n;++i)
            flow[i].resize(n);
    }

    void AddEdge(int x, int y, int c){
        G[x].emplace_back(mp(y,c));
        G[y].emplace_back(mp(x,0));
        flow[x][y] = flow[y][x] = 0;
    }

    bool bfs(){
        fill(lvl.begin(),lvl.end(),-1);
        q.push(source);
        lvl[source] = 1;
        while(!q.empty()){
            int curr = q.front();
            //cerr<< curr<< ' ';
            q.pop();
            for(auto& it: G[curr]){
                if(lvl[it.first] == -1 && flow[curr][it.first] < it.second){
                    lvl[it.first] = lvl[curr] + 1;
                    q.emplace(it.first);
                }
            }
        }
        return lvl[sink] != -1;
    }

    int send(int nod,int minflow){
        if(nod == sink)
            return minflow;
        for(;start[nod] < (int)G[nod].size(); ++start[nod]){
            auto it = G[nod][start[nod]];
            if(lvl[it.first] != lvl[nod] + 1)
                continue;
            if(flow[nod][it.first] >= it.second)
                continue;
            int departe = send(it.first,min(minflow,it.second - flow[nod][it.first]));
            if(departe){
                flow[nod][it.first] += departe;
                flow[it.first][nod] -= departe;
                return departe;
            }
        }
        return 0;
    }

    int solve(){
        int flux = 0;
        while(true){
            if(!bfs())
                break;
            fill(start.begin(),start.end(),0);
            while(int add = send(source,INT_MAX))
                flux += add;
        }
        return flux;
    }
};


int main()
{
    int n,m;
    fin>>n>>m;
    Dinic D(n,m,0,n-1);
    for(int i=0;i<m;++i){
        int a,b,c;
        fin>>a>>b>>c;
        --a;
        --b;
        D.AddEdge(a,b,c);
    }
    fout << D.solve();
}