Cod sursa(job #2958589)

Utilizator GeorgeNistorNistor Gheorghe GeorgeNistor Data 27 decembrie 2022 00:35:45
Problema Cuplaj maxim in graf bipartit Scor 52
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.69 kb
/*
 * Edmonds-Karp's algorithm
 * https://www.infoarena.ro/problema/cuplaj
 */
#include <bits/stdc++.h>

using namespace std;

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

int leftSize, rightSize, edges, s, t;
vector<pair<int, int>> parrent, inDest;
vector<vector<pair<int, pair<int, int>>>> adjListRes;

void addEdge(int u, int v){
    adjListRes[u].push_back({v, {1, adjListRes[v].size()}});
    adjListRes[v].push_back({u, {0, adjListRes[u].size()-1}});
    if(v == t)
        inDest.emplace_back(u, adjListRes[u].size()-1);
}

void init() {
    s = 0;
    t = leftSize+rightSize+1;
    parrent.resize(t+1);
    adjListRes.resize(t+1);
    for(int i = 1; i <= leftSize; i++)
        addEdge(s, i);
    for(int i = 1; i <= rightSize; i++)
        addEdge(leftSize+i, t);
}

void read(){
    in >> leftSize >> rightSize >> edges;
    init();
    for(int i = 1; i <= edges; i++){
        int u, v;
        in >> u >> v;
        addEdge(u, leftSize + v);
    }
}

bool bf(){
    vector<bool> visited(t+1);
    queue<int> q;
    q.push(s);
    visited[s] = true;
    parrent[s] = {-1, -1};
    while(!q.empty()){
        int u = q.front();
        q.pop();
        if(u == t)
            continue;
        int i = 0;
        for(auto node: adjListRes[u]){
            int v, c; // node, capacity
            v = node.first;
            c = node.second.first;
            if(!visited[v] and c){
                parrent[v] = {u, i}; // adjListRes[u][i].first == v
                visited[v] = true;
                q.push(v);
            }
            i++;
        }
    }
    return visited[t];
}

int maxFlow(){
    long max_flow = 0;
    while(bf()) {
        for (auto node: inDest) {
            int u, v, i, j, min_path = 1;
            parrent[t] = node;
            v = t;
            while (parrent[v].first != -1) {
                u = parrent[v].first;
                i = parrent[v].second;
                min_path = min(min_path, adjListRes[u][i].second.first);
                v = u;
            }
            v = t;
            while (parrent[v].first != -1) {
                u = parrent[v].first;
                i = parrent[v].second;
                j = adjListRes[u][i].second.second;
                adjListRes[u][i].second.first -= min_path;
                adjListRes[v][j].second.first += min_path;
                v = u;
            }
            max_flow += min_path;
        }
    }
    return max_flow;
}

int main(){
    read();
    out << maxFlow() << '\n';
    for(int u = 1; u <= leftSize; u++)
        for(auto node: adjListRes[u]){
            int v = node.first;
            int c = node.second.first;
            if(v && c == 0)
                out << u << " " << v-leftSize << endl;
        }
    return 0;
}