Cod sursa(job #3225474)

Utilizator andiRTanasescu Andrei-Rares andiR Data 17 aprilie 2024 17:45:21
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.69 kb
// Author: Tanasescu Andrei-Rares
// Dinic
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <deque>
#include <iomanip>
#include <vector>
#include <cassert>

#pragma GCC optimize("O3")

#define fi first
#define se second
#define pb push_back
#define pf push_front

using namespace std;

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

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const ll Nmax=1000+5, inf=1e9+5, Mmax=5000+5;

int n, m;

struct DINIC{
    int crte=0;
    struct edge{
        int a, b, c;
        int flow;
    }e[Mmax*2];
    vector<int> ad[Nmax];
    int dist[Nmax];
    bool blocked[Nmax];
    int s, t;

    inline void _add_edge(int a, int b, int c){
        e[crte]={a, b, c};
        ad[a].pb(crte++);
    }
    inline void add_edge(int a, int b, int c){
        _add_edge(a, b, c);
        _add_edge(b, a, 0);
    }
    inline bool bfs(){
        for (int i=1; i<Nmax; i++)
            dist[i]=blocked[i]=0;

        queue<int> q;
        q.push(s);
        dist[s]=1;
        while (!q.empty()){
            int crt=q.front();
            q.pop();
            for (auto it:ad[crt]){
                if (e[it].c && !dist[e[it].b]){
                    dist[e[it].b]=dist[crt]+1;
                    q.push(e[it].b);
                }
            }
        }
        return dist[t];
    }
    inline int dfs(int nod, int flow){
        if (nod==t)
            return flow;
        int pushed=0;
        blocked[nod]=1;
        for (auto it:ad[nod])
            if (dist[nod]+1==dist[e[it].b]){ // in DAG
                if (e[it].c!=e[it].flow && !blocked[e[it].b]){
                    int df=dfs(e[it].b, min(flow, e[it].c-e[it].flow));
                    pushed+=df;
                    flow-=df;
                    e[it].flow+=df;
                    if (flow==0)
                        break;
                }
                if (e[it].c!=e[it].flow && !blocked[e[it].b])
                    blocked[nod]=0;
            }
        return pushed;
    }
    inline int max_flow(int S, int T){
        int flow=0;
        s=S; t=T;
        while (bfs()){
            flow+=dfs(s, inf);

            for (int i=0; i<crte; i++){
                e[i].c-=e[i].flow;
                e[i^1].c+=e[i].flow;
                e[i].flow=0;
            }
        }
        return flow;
    }
}dinic;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    fin>>n>>m;
    int a, b, c;
    for (int i=0; i<m; i++){
        fin>>a>>b>>c;
        dinic.add_edge(a, b, c);
    }
    fout<<dinic.max_flow(1, n);

    return 0;
}