Cod sursa(job #2962182)

Utilizator adeladanescuAdela Danescu adeladanescu Data 7 ianuarie 2023 22:03:31
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.15 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

int N, M, E, dest;

vector<bool> existaDreapta;
vector<pair<int, int>> parinte;
vector<pair<int, int>> noduriDreapta;
vector<vector<pair<int, pair<int, int>>>> la;


void read()
{
    in >> N >> M >> E;
    dest = N + M + 1;
    existaDreapta.resize(M + 1);
    parinte.resize(dest + 1);
    la.resize(dest + 1);
    for (int i = 1; i <= N; i++)
    {
        //adauga muchie
        la[0].push_back({i, {1, la[i].size()}});
        la[i].push_back({0, {0, la[0].size() - 1}});
        if (i == dest)
            noduriDreapta.emplace_back(0, la[0].size() - 1);
    }

    for (int i = 1; i <= E; i++) {
        int x, y;
        in >> x >> y;
        //adauga muchie
        la[x].push_back({N+y, {1, la[N+y].size()}});
        la[N+y].push_back({x, {0, la[x].size() - 1}});
        if (N+y == dest)
            noduriDreapta.emplace_back(x, la[x].size() - 1);
        existaDreapta[y] = true;
    }
    for (int i = 1; i <= M; i++) {
        if (existaDreapta[i])
        {
            //adauga muchie
            la[N+i].push_back({dest, {1, la[dest].size()}});
            la[dest].push_back({N+i, {0, la[N+i].size() - 1}});
            noduriDreapta.emplace_back(N+i, la[N+i].size() - 1);
        }
    }
}


int bfs() {
    vector<bool> viz(dest + 1);
    queue<int> coada;
    coada.push(0);
    viz[0] = true;
    parinte[0] = {-1, -1};
    while (!coada.empty()) {
        int u = coada.front();
        coada.pop();
        int i = 0;
        for (auto node: la[u]) {
            int v, c;
            v = node.first;
            c = node.second.first;
            if (!viz[v] and c) {
                parinte[v] = {u, i};
                if (v == dest)
                    return 1;
                viz[v] = true;
                coada.push(v);
            }
            i++;
        }
    }
    return 0;
}

void maxFlow() {
    long long int max_flow = 0;
    int new_flow= bfs();
    while (new_flow) {
        for (auto node: noduriDreapta) {
            int temp, next=dest, i, j, min_path = 1;
            parinte[dest] = node;
            while (parinte[next].first != -1) {
                temp = parinte[next].first;
                i = parinte[next].second;
                min_path = min(min_path, la[temp][i].second.first);
                next = temp;
            }
            next = dest;
            while (parinte[next].first != -1) {
                temp = parinte[next].first;
                i = parinte[next].second;
                j = la[temp][i].second.second;
                la[temp][i].second.first -= min_path;
                la[next][j].second.first += min_path;
                next = temp;
            }

            max_flow += min_path;
        }
        new_flow= bfs();
    }
    out<<max_flow<<'\n';
}

int main() {
    read();
    maxFlow();
    for (int i = 1; i <= N; i++)
        for (auto node: la[i]) {
            int v, c;
            v = node.first;
            c = node.second.first;
            if (c == 0)
                if(v!=0 && v!=dest)
                out << i << " " << v - N << '\n';
        }
    return 0;
}