Cod sursa(job #998897)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 18 septembrie 2013 17:53:38
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.14 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <bitset>
using namespace std;

int st[10005],dr[10005];
bitset<10005>used;
vector<int>lv[10005];
//lv[i] se va construi pt. i din stinga shi va contzine lista vecinilor
//din dreapta
int n,m,e,x,y;

int caut_drum(const int i)
{
    used[i]=1;
    vector<int>::iterator j;
    //luam toat muchiile i,*j
    for(j=lv[i].begin();j!=lv[i].end();++j)
    //vedem daca muchia (i,*j) se termina in *j necuplat
    if(st[*j]==0)//daca da, inseamna ca drumul e gasit, intoarcem 1 shi
        //folosim muchia in cuplaj
    {
        dr[i]=*j;
        st[*j]=i;
        return 1;
    }
    else//deci *j e deja cuplat cu altcineva
    //am ales muchia (i,*j). Ideea e ca *j sa fie cuplat insa NU la loc cu i,
        //cu alte cuvinte muchia (i,*j) sa nu faca parte din cuplaj
        if(st[*j]!=i&&!used[st[*j]])
        {
            //in cazul asta e ok, pot sa continui back-ul mai departe din st[*j]
            if(caut_drum(st[*j]))
            {
                dr[i]=*j;
                st[*j]=i;
                return 1;
            }
        }
    return 0;
}

int main()
{
    FILE *f=fopen("cuplaj.in","r");
    fscanf(f,"%d%d%d",&n,&m,&e);
    int i,modif;
    for(i=1;i<=e;i++)
    {
        fscanf(f,"%d%d",&x,&y);
        lv[x].push_back(y);
        if(dr[x]==0&&st[y]==0)
        {
            dr[x]=y;st[y]=x;
        }
    }
    do
    {
        modif=0;//asta e un flag care-mi indica daca am modif. la parcurgerea
        //curenta
        for(i=1;i<=n;i++)used[i]=0;
        //vectorul used imi retzine nodurile din stinga atinse de vreun drum
        //alternant
        for(i=1;i<=n;i++)
            if(!used[i]&&dr[i]==0)//caut drum cauta cu back un drum, il shi opereaza
                        if(caut_drum(i))//shi daca-l gaseshte intoarce 1
                                    modif=1;
    }while(modif);
    FILE *fout=fopen("cuplaj.out","w");
    int nc=0;
    for(i=1;i<=n;i++)if(dr[i])nc++;
    fprintf(fout,"%d\n",nc);
    for(i=1;i<=n;i++)
        if(dr[i])
            fprintf(fout,"%d %d\n",i,dr[i]);
    return 0;
}