Cod sursa(job #2692433)

Utilizator stanciucalinStanciu Calin stanciucalin Data 2 ianuarie 2021 17:44:00
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.68 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

/// sursa adaptata dupa cea referita la indicatii

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

vector <int> * lv;

int l_card, r_card;
int n, m;

int * match;
bool * visited;

bool find_aug_path(int l_node){

    if(visited[l_node])
        return false;

    visited[l_node] = 1;

    /// caz de baza al cand nodul din dreapta poate fi cuplat direct cu nodul din stanga necuplat
    for(int i = 0; i < lv[l_node].size(); i++){

        int r_node = lv[l_node][i];

        if(!match[r_node]){

            match[l_node] = r_node;
            match[r_node] = l_node;

            return true;
        }
    }

    /// daca nu am noduri cu care sa pot cupla direct nodul curent, caut urmatoarele 2 muchii alternante
    /// de pe drumul de augumentat

    for(int i = 0; i < lv[l_node].size(); i++){

        int r_node = lv[l_node][i];
        int next_l_node = match[r_node]; /// garantat va fi /= 0 datorita for ului de mai sus

        /// apelez recursiv find_aug_path; daca la finalul stivei apelului se ajunge
        /// la cazul de baza, atribuirile facute refac cuplajele corespunzatoare de pe aug_path
        /// array ul visited ma ajuta sa nu ciclez
        if(find_aug_path(next_l_node)){

            match[l_node] = r_node;
            match[r_node] = l_node;

            return true;
        }
    }

    /// nu am gasit nici un augumenting path
    return false;
}

void Hopcroft(){

    bool aug_path_found;

    /// execut cat timp la fiecare pas gasesc cel putin un augumenting path (actualizez cuplajul)
    do{
        aug_path_found = 0;

        for(int i = 1; i <= l_card; i++)
            visited[i] = 0;

        for(int l_node = 1; l_node <= l_card; l_node++)

            if(!match[l_node]){
                aug_path_found |= find_aug_path(l_node);
            }
    }
    while(aug_path_found);
}

int main(){

    f >> l_card >> r_card >> m;

    n = l_card + r_card;

    lv = new vector <int> [l_card + 1];

    match = new int [n + 1];
    visited = new bool [l_card + 1];

    for(int i = 1; i <= n; i++)
        match[i] = 0;

    int x, y;
    for(int i = 0; i < m; i++){

        f >> x >> y;
        lv[x].push_back(y + l_card);
    }

    Hopcroft();

    int max_matching = 0;

    for(int l_node = 1; l_node <= l_card; l_node++)
        if(match[l_node])
            max_matching += 1;

    g << max_matching << '\n';

    for(int l_node = 1; l_node <= l_card; l_node++){

        if(match[l_node])
            g << l_node << " " << match[l_node] - l_card << '\n';
    }

    return 0;
}