Nu exista pagina, dar poti sa o creezi ...

Cod sursa(job #2806776)

Utilizator MatteoalexandruMatteo Verzotti Matteoalexandru Data 22 noiembrie 2021 23:16:24
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.21 kb
/*
                `-/oo+/-   ``
              .oyhhhhhhyo.`od
             +hhhhyyoooos. h/
            +hhyso++oosy- /s
           .yoooossyyo:``-y`
            ..----.` ``.-/+:.`
                   `````..-::/.
                  `..```.-::///`
                 `-.....--::::/:
                `.......--::////:
               `...`....---:::://:
             `......``..--:::::///:`
            `---.......--:::::////+/`
            ----------::::::/::///++:
            ----:---:::::///////////:`
            .----::::::////////////:-`
            `----::::::::::/::::::::-
             `.-----:::::::::::::::-
               ...----:::::::::/:-`
                 `.---::/+osss+:`
                   ``.:://///-.
*/
#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << '\n'
#define debugsp(x) cerr << #x << " " << x << ' '

using namespace std;

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

const int INF = 2e9;

class Flow_Graph {
private:

    struct Edge {
        int from, to, cap, flow;

        Edge (int from, int to, int cap) 
            : from(from), to(to), cap(cap) , flow(0) {}
    };

    int n, m;
    vector <vector <int>> adj;
    vector <int> lev, rem;
    vector <Edge> edges;

public:

    Flow_Graph(int n) : n(n), m(0) {
        adj.resize(1 + n);
        lev.resize(1 + n);
        rem.resize(1 + n);
    }

    void addEdge (int from, int to, int w) {
        edges.push_back(Edge {from, to, w});
        edges.push_back(Edge {to, from, 0});
    
        adj[from].push_back(m);
        adj[to].push_back(m + 1);

        m += 2;
    }

    bool BFS() { 
        fill (lev.begin(), lev.end(), 0);

        queue <int> q;
        q.push(1);
        lev[1] = 1;

        while (!q.empty()) {
            int from = q.front();
            q.pop();
            
            for (int it : adj[from]) {
                Edge e = edges[it];
                
                if (e.cap > e.flow && lev[e.to] == 0) {
                    lev[e.to] = 1 + lev[e.from];
                    q.push(e.to);
                }
            }
        }

        return (lev[n] > 0);
    }
    
    int DFS (int node, int need) {
        if (need == 0) return 0;
        if (node == n) return need;

        int curr_flow = 0;

        for (int &it = rem[node]; it < (int) adj[node].size(); it++) {
            int id = adj[node][it];

            if (lev[edges[id].to] == 1 + lev[node] && edges[id].flow < edges[id].cap) {
                int flow = DFS (edges[id].to, min (need , edges[id].cap - edges[id].flow));
                
                edges[id].flow += flow;
                edges[id ^ 1].flow -= flow;

                curr_flow += flow;
                need -= flow;
            }
        }

        return curr_flow;
    }

    int maxFlow() {
        int ans = 0;

        while (BFS() == true) {
            fill (rem.begin(), rem.end(), 0);
            
            while (int flow = DFS (1, INF))
                ans += flow;
        }

        return ans;
    }
};

int main() {
    int n, m;

    in >> n >> m;

    Flow_Graph g (n);

    for (int i = 1; i <= m; i++) {
        int x, y, w;
        in >> x >> y >> w;
        g.addEdge(x, y, w);
    }

    out << g.maxFlow() << '\n';
    in.close();
    out.close();
    return 0;
}