Cod sursa(job #1652565)

Utilizator dorupopDoru Pop dorupop Data 15 martie 2016 08:49:01
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.85 kb
#include<fstream>
#include<vector>
#include<cstring>

#define NMax 10001

using namespace std;

vector<int> graph[NMax];
int n,m,e;
int used[NMax];//nodurile folosite intr-o iteratie
int st[NMax],dr[NMax];//cuplajele realizate - in ambele sensuri


int cuplaj(int ind)
{
    if(used[ind])return 0;//daca a mai fost folosit in interatia curenta, ne intoarcem
    used[ind]=1;//il marcam ca fiind folosit

    for(vector<int>::iterator it=graph[ind].begin();it!=graph[ind].end();it++)
        if(dr[*it]==0)//incercam mai intai sa-l cuplam cu un nod adiacent liber
        {
            st[ind]=*it;
            dr[*it]=ind;
            return 1;//daca reusim, ne intoarcem
        }

    for(vector<int>::iterator it=graph[ind].begin();it!=graph[ind].end();it++)
        if(cuplaj(dr[*it]))//inceram a doua oara sa eliberam un nod adiacent ocupat
        {
            st[ind]=*it;
            dr[*it]=ind;
            return 1;//daca reusim sa eliberam un loc, il cuplam cu nodul curent
        }

    return 0;//daca nu reusim sa-l cuplam
}

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

    f>>n>>m>>e;

    for(int i=1;i<=e;++i)//citim graful
    {
        int x,y;
        f>>x>>y;
        graph[x].push_back(y);
    }

    int change=1;
    while(change)//cat timp s-a facut o cuplare in iteratia anterioara => este posibil sa mai putem cupla ceva
    {
        change=0;
        memset(used,0,sizeof(used));//resetam used

        for(int i=1;i<=n;++i)
            if(!st[i])
                 change+=cuplaj(i);//daca nodul curent nu e cuplat, incercam sa-l cuplam
    }

    int nr=0;
    for(int i=1;i<=n;i++)
        if(st[i])
            nr++;//numaram cuplajele

 g<<nr<<'\n';

    for(int i=1;i<=n;i++)
            if(st[i])
               g<<i<<" "<<st[i]<<'\n';//scriem cuplajele
}