Cod sursa(job #901073)

Utilizator costi_.-.Costinnel costi_.-. Data 1 martie 2013 00:03:00
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include<fstream>
#include<cstring>
#include<iostream>
#define nmax 2004
using namespace std;

struct nod_lista{
    int val;
    nod_lista *link;
};

nod_lista *G[nmax],*Last[nmax];
int T[nmax],viz[nmax],Q[nmax],C[nmax][nmax],F[nmax][nmax],Left[nmax],Right[nmax];
bool bL[nmax],bR[nmax];
int L,R,E,N,S,D,kR,kL,cuplaj;

void adauga(int unde,int ce)
{
    nod_lista *q=new nod_lista;

    q->val=ce;
    q->link=NULL;
    if(!G[unde])
    G[unde]=Last[unde]=q;
    else
    {
        Last[unde]->link=q;
        Last[unde]=q;
    }
}

void citeste()
{
    ifstream f("cuplaj.in");
    int i,x,y;

    f>>L>>R>>E;
    S=L+R+1;
    D=L+R+2;

    for(i=1;i<=E;i++)
    {
        f>>x>>y;
        adauga(x,y+L);
        adauga(y+L,x);

        //Left[] va contine toate nodurile din stanga
        if(!bL[x])
        {
            Left[++kL]=x;
            bL[x]=true;
        }
        //Right[] va contine toate nodurile din dreapta                ;
        if(!bR[y])
        {
            Right[++kR]=y;
            bR[y]=true;
        }

        C[x][y+L]=1;
    }

    for(i=1;i<=L;i++)
    {
        adauga(S,Left[i]);
        //adauga(Left[i],S);
        C[S][Left[i]]=1;
    }

    //Stabilesc legaturile S->St si DR->D
    for(i=1;i<=R;i++)
    {
        adauga(Right[i]+L,D);
        adauga(D,Right[i]+L);
        C[Right[i]+L][D]=1;
    }
}

int BFS(int S,int D)
{
    int nod,p,q;
    nod_lista *it;

    memset(viz,0,sizeof(viz));
    memset(T,0,sizeof(T));

    p=q=0;
    Q[++q]=S;
    viz[S]=1;

    while(p<q)
    {
        nod=Q[++p];
        it=G[nod];
        if(nod!=D)
        while(it)
        {
            if(C[nod][it->val]>F[nod][it->val] && !viz[it->val])
            {
                viz[it->val]=1;
                Q[++q]=it->val;
                T[it->val]=nod;
            }
            it=it->link;
        }
    }

    return viz[D];
}

void satureaza()
{
    int nod;
    nod_lista *q=G[D];
    while(q)
    {
         nod=q->val;
           if(viz[nod] && !F[nod][D])
             {
                T[D]=nod;
                nod=D;
                while(nod!=S)
                  {
                     ++F[T[nod]][nod]; //capacitatea minima e 1, am zis ca n-are rost s-o mai determin
                      --F[nod][T[nod]];
                      nod=T[nod];
                 }

              ++cuplaj;
             }

    q=q->link;
 }
}



void rezolva()
{
    while(BFS(S,D))
    {
        satureaza();
    }
}

void scrie()
{
    ofstream g("cuplaj.out");
    int i; nod_lista *q;
    g<<cuplaj<<'\n';

    for(i=1;i<=L;i++)
    {
        q=G[Left[i]];
        while(q)
        {
            if(F[Left[i]][q->val]==1)
            {
                g<<Left[i]<<' '<<q->val-L;
                g<<'\n';
            }
            q=q->link;
        }
    }

    g.close();
}

int main()
{
    citeste();
    rezolva();
    scrie();
    return 0;
}