Cod sursa(job #2958511)

Utilizator GeorgeNistorNistor Gheorghe GeorgeNistor Data 26 decembrie 2022 20:17:48
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 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; // parrent[u] = {v, adjListRes[v].second.second} where adjListRes[v].first = u
vector<vector<pair<int, pair<int, int>>>> adjListRes; // adjList[u] = {v, {0/1, index}}

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}});
}

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();
        for(auto node: adjListRes[u]){
            int v, c, i; // node, capacity, index
            v = node.first;
            c = node.second.first;
            i = adjListRes[v][node.second.second].second.second;
            if(!visited[v] and c){
                parrent[v] = {u, i}; // adjListRes[u][i].first == v
                if(v == t)
                    return true;
                visited[v] = true;
                q.push(v);
            }
        }
    }
    return false;
}

int maxFlow(){
    long max_flow = 0;
    set<int> temp;
    while(bf()){
        int v, u, i, j;
        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 = 0;
            adjListRes[v][j].second.first = 1;
            v = u;
        }
        max_flow += 1;
    }
    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;
}