Cod sursa(job #2616667)

Utilizator MatteoalexandruMatteo Verzotti Matteoalexandru Data 19 mai 2020 17:49:43
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.81 kb
/*
                `-/oo+/-   ``
              .oyhhhhhhyo.`od
             +hhhhyyoooos. h/
            +hhyso++oosy- /s
           .yoooossyyo:``-y`
            ..----.` ``.-/+:.`
                   `````..-::/.
                  `..```.-::///`
                 `-.....--::::/:
                `.......--::////:
               `...`....---:::://:
             `......``..--:::::///:`
            `---.......--:::::////+/`
            ----------::::::/::///++:
            ----:---:::::///////////:`
            .----::::::////////////:-`
            `----::::::::::/::::::::-
             `.-----:::::::::::::::-
               ...----:::::::::/:-`
                 `.---::/+osss+:`
                   ``.:://///-.
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <cmath>

using namespace std;

const int INF = 2e9;
const int N = 1e3;

/*template <typename Type>
class Queue {
    private:
        int sz = 0;

        struct element {
            Type val;
            element *next;

            element() {
                val = 0;
                next = nullptr;
            }
        };
        element *first, *last;

    public:
        Queue () {
            sz = 0;
        }

        void Push(Type val) {
            element *aux = new element;

            aux -> val = val;

            if(sz == 0) {
                first = aux;
                last = aux;
            } else {
                last -> next = aux;
                last = aux;
            }

            sz++;
            return;
        }

        void Pop() {
            element *aux = first;
            first = first -> next;

            delete aux;
            sz--;

            return;
        }

        void Clear() {
            while(sz) Pop();

            return;
        }

        Type Front() { return first -> val; }
        Type Back()  { return last -> val; }
        int Size()   { return sz; }
        bool Empty() { return sz == 0; }
};*/

template <typename Type>
class Flow_Graph {
    private:

        int sz;

        struct Edge {
            int to;
            Type flow, c;
            int rev;
        };

        vector <vector <Edge>> adj;
        vector <Type> lev, rem;

    public:
        Flow_Graph (int n) {
            sz = n;
            adj.resize(1 + n);
            lev.resize(1 + n);
            rem.resize(1 + n);
        }

        void AddEdge(int from, int to, Type C) {
            Edge x {to, 0, C, adj[to].size()};
            Edge y {from, 0, 0, adj[from].size()};

            adj[from].push_back(x);
            adj[to].push_back(y);
        }

        bool BFS() {
            for(int i = 1; i <= sz; i++)
                lev[i] = 0;
            lev[1] = 1;

            queue <int> q;
            q.push(1);

            while(!q.empty()) {
                int from = q.front();
                q.pop();

                for(Type it = 0; it < adj[from].size(); it++) {
                    Edge &e = adj[from][it];

                    if(!lev[e.to] && e.flow < e.c) {
                        lev[e.to] = 1 + lev[from];

                        q.push(e.to);
                    }
                }
            }

            return (lev[sz] > 0);
        }

        Type DFS(Type from, Type flow) {
            if(from == sz) return flow;

            for(Type &it = rem[from]; it < adj[from].size(); it++) {
                Edge &e = adj[from][it];

                if(lev[e.to] == 1 + lev[from] && e.flow < e.c) {
                    Type curr_flow = min(flow, e.c - e.flow);

                    Type temp_flow = DFS(e.to, curr_flow);

                    if(temp_flow) {
                        e.flow += temp_flow;
                        adj[e.to][e.rev].flow -= temp_flow;

                        return temp_flow;
                    }
                }
            }

            return 0;
        }

        Type MaxFlow() {
            Type ans = 0;

            while(BFS() == true) {
                for(int i = 1; i <= sz; i++)
                    rem[i] = 0;
                Type flow = DFS(1, INF);

                while(flow) {
                    ans += flow;
                    flow = DFS(1, INF);
                }
            }

            return ans;
        }
};

int main() {
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);
    int n, m;

    scanf("%d%d", &n, &m);
    Flow_Graph <int> G(n);

    for(int i = 1; i <= m; i++) {
        int x, y, f;
        scanf("%d%d%d", &x, &y, &f);

        G.AddEdge(x, y, f);
    }

    printf("%d\n", G.MaxFlow());
    return 0;
}