Cod sursa(job #3263975)

Utilizator raizoSoare Antonio raizo Data 17 decembrie 2024 13:51:18
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.07 kb
#include <fstream>
#include <vector>
#include <map>
#include <queue>
#include <climits>
using namespace std;

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

int n, m, x, y, c;

struct edge {
    int capacity;
    int flow;
    int residual;
};

struct node {
    int excess_flow;
    int height;
};

void relable(map<int, map<int, edge>>& mat, vector<node>& nodes, int node) {
    int mini = INT_MAX;
    for (auto& item : mat[node]) {
        int next = item.first;
        edge& current = item.second;
        if (current.residual > 0) {
            mini = min(mini, nodes[next].height);
        }
    }
    nodes[node].height = mini + 1;
}

void push(map<int, map<int, edge>>& mat, vector<node>& nodes, int node, int next) {
    edge& current = mat[node][next];
    edge& reverse = mat[next][node];
    
    int pushed_flow = min(current.residual, nodes[node].excess_flow);
        
    current.flow += pushed_flow;
    reverse.flow -= pushed_flow;
    
    current.residual = current.capacity - current.flow;
    reverse.residual = reverse.capacity - reverse.flow;

    nodes[next].excess_flow += pushed_flow;
    nodes[node].excess_flow -= pushed_flow;
}

void init(map<int, map<int, edge>>& mat, vector<node>& nodes, queue<int>& q, int source, int sink) {
    nodes[source].height = n;
    nodes[source].excess_flow = INT_MAX;
    for (auto& item : mat[source]) {
        int next = item.first;
        push(mat, nodes, source, next);
        if (nodes[next].excess_flow > 0 && next != source && next != sink) {
            q.push(next);
        }
    }
}

int maxflow(map<int, map<int, edge>>& mat, int source = 1, int sink = n) {

    queue<int> q;
    vector<node> nodes(n + 1, { 0,0 });
    init(mat, nodes, q, source, sink);

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

        for (auto& item : mat[node]) {
            int next = item.first;
            edge& current = item.second;

            if (nodes[node].excess_flow <= 0) {
                break;
            }
            if (current.residual > 0 && nodes[node].height > nodes[next].height) {
                push(mat, nodes, node, next);
                if (nodes[next].excess_flow > 0 && next != source && next != sink) {
                    q.push(next);
                }
            }
        }

        if (nodes[node].excess_flow > 0) {
            relable(mat, nodes, node);
        }
        else {
            q.pop();
        }
    }

    return nodes[sink].excess_flow;
}

int main()
{
    cin >> n >> m;
    map<int, int> aux;
    map<int, map<int, edge>> mat;

    for (int i = 0; i < m; i++) {
        cin >> x >> y >> c;
        auto it = mat[x].find(y);
        if (it == mat[x].end()) {
            mat[x][y].capacity = c;
            mat[x][y].residual = c;

            mat[y][x].capacity = 0;
            mat[y][x].residual = 0;
        }
        else {
            mat[x][y].capacity = c;
            mat[x][y].residual = c;
        }
    }

    int result = maxflow(mat);

    cout << result << endl;
}