Cod sursa(job #631571)

Utilizator blustudioPaul Herman blustudio Data 8 noiembrie 2011 18:26:40
Problema Cuplaj maxim in graf bipartit Scor 14
Compilator cpp Status done
Runda Arhiva educationala Marime 3.1 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

struct muchie
{
    int a, b;
};
struct nod
{
    bool vizitat;
    bool cuplat;
    vector<int> vecini;
};

int cardinal_cuplaj;
int cuplaj_stanga[10001];
int cuplaj_dreapta[10001];
int noduri_stanga, noduri_dreapta;
int muchii;
nod noduri[20001];

inline void citire()
{
    ifstream fin("cuplaj.in");
    fin >> noduri_stanga >> noduri_dreapta >> muchii;
    int a, b;
    for (int i = 0; i < muchii; i++)
    {
        fin >> a >> b;
        b = b + noduri_stanga;
        noduri[a].vecini.push_back(b);
        noduri[b].vecini.push_back(a);
    }
    fin.close();
}
bool cauta_pereche(int s)
{
    noduri[s].vizitat = true;
    bool pereche_gasita = false;
    for (int i = 0; (i < noduri[s].vecini.size()) && (pereche_gasita == false); i++)
    {
        if (noduri[noduri[s].vecini.at(i)].cuplat == false)
        {
            noduri[s].cuplat = true;
            noduri[noduri[s].vecini.at(i)].cuplat = true;
            cuplaj_stanga[s] = noduri[s].vecini.at(i) - noduri_stanga;
            cuplaj_dreapta[noduri[s].vecini.at(i) - noduri_stanga] = s;
            pereche_gasita = true;
        }
    }
    if (pereche_gasita == true)
        return true;
    for (int i = 0; (i < noduri[s].vecini.size()) && (pereche_gasita == false); i++)
    {
        if (noduri[cuplaj_dreapta[noduri[s].vecini.at(i) - noduri_stanga]].vizitat == false)
        {
            if (cauta_pereche(cuplaj_dreapta[noduri[s].vecini.at(i) - noduri_stanga]) == true)
            {
                noduri[s].cuplat = true;
                noduri[noduri[s].vecini.at(i)].cuplat = true;
                cuplaj_stanga[s] = noduri[s].vecini.at(i) - noduri_stanga;
                cuplaj_dreapta[noduri[s].vecini.at(i) - noduri_stanga] = s;
                pereche_gasita = true;
            }
        }
    }
    if (pereche_gasita == true)
        return true;
    return false;
}
inline void hopcroft_karp()
{
    cardinal_cuplaj = 0;
    int perechi_gasite;
    do {
        perechi_gasite = 0;
        for (int i = 1; i <= noduri_stanga; i++)
            if (noduri[i].cuplat == false)
                if (cauta_pereche(i) == true)
                    perechi_gasite++;
        cardinal_cuplaj += perechi_gasite;
    } while (perechi_gasite > 0);
            //Cautam un nod din dreapta necuplat
            //Daca toate nodurile din dreapta sunt toate cuplate
                //Pt fiecare vecin al nodului curent
                    //Daca pt perechea nodului din dreapta gasim alta pereche
                        //Cuplam nodul din stanga cu cel din dreapta
                //Altfel algoritmul s-a terminat
            //Altfel algoritmul s-a terminat
}
inline void scriere()
{
    ofstream fout("cuplaj.out");
    fout << cardinal_cuplaj;
    for (int i = 0; i < noduri_stanga; i++)
        if (cuplaj_stanga[i] > 0)
            fout << '\n' << i << ' ' << cuplaj_stanga[i];
    fout.close();
}
int main()
{
    citire();
    hopcroft_karp();
    scriere();
    return 0;
}