Cod sursa(job #3261334)

Utilizator raizoSoare Antonio raizo Data 5 decembrie 2024 15:25:31
Problema Flux maxim Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.44 kb
#include <fstream>
#include <vector>
#include <deque>
#include <unordered_map>
#include <climits>
using namespace std;

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

int n, m, x, y, c;
struct edge {
    int x;
    int y;
    int capacity;
    bool reverse = false;
    int flow = 0;
    int residual = capacity;
};

void dfs(deque<int>& path, int& best_flow, vector<unordered_map<int, edge>>& list, vector<int>& visited, int flow = INT_MAX, int dest = n) {
    int current = path[path.size() - 1];
    if (current == dest) {
        best_flow = flow;
    }
    else if (current != dest) {
        for (auto& item : list[current]) {
            edge e = item.second;
            int possible_flow = min(flow, e.residual);
            if (possible_flow > visited[e.y]) { 
                visited[e.y] = possible_flow;
                path.push_back(e.y);
                dfs(path, best_flow, list, visited, possible_flow);
                if (best_flow != 0) {
                    break;
                }
                path.pop_back();
            }
        }
    }
}


void update(edge& e, edge& r, int flow) {
    if (!e.reverse) {
        e.flow += flow;
        e.residual = e.capacity - e.flow;
        r.residual = e.flow;
    }
    else {
        edge& aux = e;
        e = r;
        r = aux;
        e.flow -= flow;
        e.residual = e.capacity - e.flow;
        r.residual = e.flow;
    }
}

int ford_fulkerson(vector<unordered_map<int, edge>>& list, int source = 1, int dest = n) {
    int max_flow = 0;
    while (true) {

        int flow = 0;
        deque<int> path;
        vector<int> visited(n + 1, 0);
        path.push_back(source);
        visited[source] = INT_MAX;
        dfs(path, flow, list, visited);

        if (path.size() == 0 || path[path.size() - 1] != dest) {
            break;
        }

        for (int i = 0; i < path.size() - 1; i++) {
            x = path[i];
            y = path[i + 1];
            update(list[x][y], list[y][x], flow);
        }

        max_flow += flow;
    }
    return max_flow;
}


int main()
{
    cin >> n >> m;
    unordered_map<int, edge > map;
    vector<unordered_map<int, edge>> list(n + 1, map);
    for (int i = 0; i < m; i++) {
        cin >> x >> y >> c;
        list[x][y] = { x,y,c,false };
        list[y][x] = { y,x,0,true };
    }

    int result = ford_fulkerson(list);

    cout << result << endl;
}