Cod sursa(job #2962467)

Utilizator AntoniaPopoviciAntonia-Adelina Popovici AntoniaPopovici Data 8 ianuarie 2023 17:12:21
Problema Cuplaj maxim in graf bipartit Scor 4
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.91 kb
#include <bits/stdc++.h>
#include <queue>
#include <vector>

using namespace std;

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

const int INF = INT_MAX;

int nr_noduri, dest;
vector<vector<int>> adj;
int flux_maxim = 0, flux_minim, firstelem;
vector<int> tata, dist;
vector<bool> vizitat;

struct muchie {
    int nod1, nod2, flux, poz;
};

vector<muchie> muchii;

bool dijkstra() {
    dist.clear();
    dist.resize(nr_noduri + 1, INF);
    vizitat.clear();
    vizitat.resize(nr_noduri + 1, false);
    dist[0] = 0;

    priority_queue<pair<int, int>, vector<pair<int, int>>,
        greater<pair<int, int>>>
        pq;
    pq.push({ 0, 0 });

    while (!pq.empty()) {
        int u = pq.top().second;
        pq.pop();

        if (vizitat[u])
            continue;
        vizitat[u] = true;

        for (auto p : adj[u]) {
            muchie edge = muchii[p];
            int v = edge.nod2;
            if (edge.flux > 0 && dist[v] > dist[u] + 1) {
                dist[v] = dist[u] + 1;
                tata[v] = p;
                pq.push({ dist[v], v });
            }
        }
    }

    return vizitat[dest];
}

void revizuire_flux() {
    flux_minim = INF;

    int element = dest;
    while (element != 0) {
        muchie edge = muchii[tata[element]];
        flux_minim = min(flux_minim, edge.flux);
        element = edge.nod1;
    }

    element = dest;
    while (element != 0) {
        muchie edge = muchii[tata[element]];
        muchii[tata[element]].flux -= flux_minim;
        muchii[edge.poz].flux += flux_minim;
        element = edge.nod1;
    }

    flux_maxim += flux_minim;
}

int main() {
    int card_L, card_R, nr_muchii;
    f >> card_L >> card_R >> nr_muchii;

    nr_noduri = card_L + card_R + 2;
    dest = nr_noduri - 1;

    adj.resize(nr_noduri + 1);
    tata.resize(nr_noduri + 1);
    vizitat.resize(nr_noduri + 1);
    int x, y;

    for (int i = 1; i <= nr_muchii; i++) {
        f >> x >> y;
        muchii.push_back({ x, y + card_L, 1, 2 * i - 1 });
        muchii.push_back({ y + card_L, x, 0, 2 * i - 2 });

        adj[y + card_L].push_back(2 * i - 1);
        adj[x].push_back(2 * i - 2);
    }

    int dim_muchii = int(muchii.size());

    for (int i = 1; i <= card_L; i++) {
        dim_muchii += 2;
        muchii.push_back({ 0, i, 1, dim_muchii - 1 });
        adj[i].push_back(dim_muchii - 1);
        muchii.push_back({ i, 0, 0, dim_muchii });
        adj[0].push_back(dim_muchii);
    }

    for (int i = card_L + 1; i <= card_L + card_R; i++) {
        dim_muchii += 2;
        muchii.push_back({ i, nr_noduri - 1, 1, dim_muchii - 1 });
        adj[nr_noduri - 1].push_back(dim_muchii - 1);
        muchii.push_back({ nr_noduri - 1, i, 0, dim_muchii });
        adj[i].push_back(dim_muchii);
    }

    while (dijkstra()) {
        revizuire_flux();
    }

    g << flux_maxim;
}