Cod sursa(job #2586077)

Utilizator Mirela_MagdalenaCatrina Mirela Mirela_Magdalena Data 19 martie 2020 18:32:11
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#define oo 0x3f3f3f3f
#define NMAX 10005
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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

typedef pair<int, int> pii;

int n, m, e, nrM;

int isPairedU[NMAX], isPairedV[NMAX];
vector<int> Gu[NMAX]; // gu[u].push_back(v) - de la u la v


void read()
{
    int x, y;
    f>>n>>m>>e;
    for(int i = 1; i <= e; ++i)
    {
        f>>x>>y;
        Gu[x].push_back(y);
    }
}

queue<int> Q;
int dmin[NMAX];
bool bfs()
{
    // trebuie pornit drumul minim (dpdv al muchiilor parcurse) ALTERNANT (folosit-nefolosit) din toate nodurile din U neviz
    for(int vf = 1; vf <= n; ++vf){
        if(isPairedU[vf] == 0)
        {
            Q.push(vf);
            dmin[vf] = 0;
        }
        else dmin[vf] = oo;
    }
    dmin[0] = oo;
    while(!Q.empty())
    {
        int top = Q.front();
        Q.pop();
        if(dmin[top] < dmin[0])
            for(auto v:Gu[top])
                if(dmin[isPairedV[v]] == oo) // top -> (muchie nefol) v -> (muchie fol) isPairedV[v] (drum altern)
                {
                    dmin[isPairedV[v]] = dmin[top] + 1; // daca v nu a fost 'cuplat' (isPaired=0) se modif dmin[0] => nu caut d mai lungi
                    Q.push(isPairedV[v]);
                }
    }

    return dmin[0]!=oo; // am gasit un drum
}

bool dfs(int x)
{
    if(x == 0)
        return 1;
    for(auto &y:Gu[x])
        if(dmin[isPairedV[y]] == dmin[x]+1 && dfs(isPairedV[y]))
        {
            isPairedU[x] = y;
            isPairedV[y] = x;
            return 1;
        }
    dmin[x] = oo;
    return 0;
}





void hopcroft_karp()
{
    while(bfs())
    {
        for(int u = 1; u <= n; ++u) // gaseste un vf nevizitat in U
            if(isPairedU[u] == 0 && dfs(u)) // refac M (in dfs)
                nrM++; // numarul de muchii din cuplaj
    }
}

void write()
{
    g<<nrM<<"\n";
    for(int u = 1; u <= n; ++u)
        if(isPairedU[u])
            g<<u<<" "<<isPairedU[u]<<'\n';
}



int main()
{
    read();
    hopcroft_karp();
    write();
    return 0;
}