Cod sursa(job #2755124)

Utilizator AndreiDeltaBalanici Andrei Daniel AndreiDelta Data 26 mai 2021 19:53:31
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.7 kb
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
typedef long long ll;
typedef pair<int,int> pi;
int t,T;

const int dim=1e4+10;
int cardL,cardR,m;
vector < int > L[dim],viz(dim,0);
vector < int > LtoR(dim,0),RtoL(dim,0);

bool Hopcroft_Karp(int u) //returneza daca se poate gasi o muchie ce pleaca din u care sa intre in cuplaj
{
    //Is la nodul u1.Nodul adiacent v1 este ocupat!Iau eu nodul v1 pentru u1 daca
    //gasesc un alt nod pentru RtoL[v1].Sunt la nodul RtoL[v1].Am trecut de primul for.Nicuin nod  disponibil
    //aleg alt nod si stabilesc legatrura pentru RtoL[RtoL[v12]].Acesta ma duce la v1 care e in curs de procesare...

    if(viz[u]==true) //s-a trecut inainte prin acest nod pentru a forma un cuplaj
        return false; //evit de a procesa doua noduri identice in paralel

    viz[u]=true;

    //verific daca exista un nod in lista de adiacenta a lui u cara sa nu fi participat in cuplaj
    for(int v:L[u])
    if(RtoL[v]==0) //nodul v nu a stabilit nicio legatura cu o muchie.E disponibil!
    {
        LtoR[u]=v;
        RtoL[v]=u;
        return true;
    }

    //toate nodurile adiacente varfului u intra in cuplaj.Nici unul nu e diponibil!
    //incerc sa eliberez nodul adiacent v pentru nodul meu u
    //pentru asta rulez recursiv procedura pentru nodul anterior care era in cuplaj cu v
    for(int v:L[u])
    {
        if(Hopcroft_Karp(RtoL[v])==true)//nodul RtoL[v] a gasit un alt nod pentru a realiza un cuplaj
        {
            LtoR[u]=v;
            RtoL[v]=u;
            return true;
        }
    }
    return false;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    f>>cardL>>cardR>>m;
    for(int i=1;i<=m;i++)
    {
        int a,b;
        f>>a>>b;
        L[a].pb(b);

    }
    int cnt=0;
    while(true)
    {
        //vectorul viz imi spune ce noduri sunt in recurenta in curs de procesare
        //ma ajuta sa evit sa procesez simultan doua noduri identice
        for(int i=1;i<=cardL;i++)
            viz[i]=0;

        bool found=0;
        for(int i=1;i<=cardL;i++)
        if(!LtoR[i]) //nu avem corespodenta pentru nodul i
        {
            //rulez procedura Hopcroft_Karp care imi spune daca
            //a putut gasi o corespodenta pentru nodul meu i

            bool op=Hopcroft_Karp(i);

            if(op==true)
            {
                cnt++;
                found=1;
            }
        }

        if(found==0) //nu s au mai gasit corespodente
            break;
    }

    g<<cnt<<'\n';
    for(int i=1;i<=cardL;i++)
        if(LtoR[i]) g<<i<<' '<<LtoR[i]<<'\n';

    return 0;
}