Cod sursa(job #720329)

Utilizator ioalexno1Alexandru Bunget ioalexno1 Data 22 martie 2012 16:07:44
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.9 kb
// Cuplaj maxim in graf bipartit realizat cu algoritmul lui Edmonds Karp
#include <cstdio>
#define N 20005
#define inf 1999999999
using namespace std;
struct nod{ int val; nod *urm; }*G[N];
struct cp{ int cap; int flux; }*GF[N][N];
int n,m,viz[N],tata[N],c[N],SS,SD,pas,maxflow;
int sol,cx[N],cy[N];
void add(int x, int y, int z)
{ nod *aux;
  cp *adr;
aux=new nod; aux->val=y;  aux->urm=G[x]; G[x]=aux;
adr=new cp; adr->cap=z; adr->flux=0; GF[x][y]=adr;
}
void read()
{ int i,x,y,e;
freopen("cuplaj.in","r",stdin); scanf("%d %d %d\n",&n,&m,&e);
// Nodurile din multimea L le consideram cu indici de la 1 la n
// Nodurile din multimea R le consideram cu indici de la n+1 la m
for(i=1;i<=e;++i)
    {
    scanf("%d %d\n",&x,&y);
    add(x,y+n,1);
    add(y+n,x,0);
    }
fclose(stdin);
}
int bf()
{ int p,u;
  nod *aux;
p=u=1; c[1]=SS; viz[SS]=pas; tata[SS]=0;
while(p<=u)
    {
    if(c[p]!=SD)
        {
         for(aux=G[c[p]];aux!=NULL;aux=aux->urm)
            if(viz[aux->val]!=pas&&GF[c[p]][aux->val]->cap>GF[c[p]][aux->val]->flux)
                {
                c[++u]=aux->val; viz[aux->val]=pas; tata[aux->val]=c[p];
                }
        }
    ++p;
    }
if(viz[SD]==pas)return 1;
    else return 0;
}
inline int min(int x,int y)
{
if(x<y)return x;
    else return y;
}
void solve()
{ nod *aux;
  int i,fm;
pas=1;
while(bf())
    {
    for(aux=G[SD];aux!=NULL;aux=aux->urm)
        if(viz[aux->val]==pas&&GF[aux->val][SD]->cap>GF[aux->val][SD]->flux)
            {
            tata[SD]=aux->val; fm=inf;
            for(i=SD;i!=SS;i=tata[i])
                fm=min(fm,GF[tata[i]][i]->cap-GF[tata[i]][i]->flux);
            if(fm)
                {
                for(i=SD;i!=SS;i=tata[i])
                    {
                    GF[tata[i]][i]->flux+=fm;
                    GF[i][tata[i]]->flux-=fm;
                    }
                }
            }
    ++pas;
    }
}
void constr_sol()
{ int i,x;
  bool e;
  nod *aux;
for(i=1;i<=n;++i)
    {
    e=false; x=0;
    for(aux=G[i];aux!=NULL&&!e;aux=aux->urm)
        if(GF[i][aux->val]->flux==1)
                {
                e=true; x=aux->val-n;
                }
    if(e)
        {
        // Avem cuplate nodurile i din L cu x din R
        ++sol;
        cx[sol]=i; cy[sol]=x;
        }
    }
}
void write()
{ int i;
freopen("cuplaj.out","w",stdout); printf("%d\n",sol);
for(i=1;i<=sol;++i)
    printf("%d %d\n",cx[i],cy[i]);
fclose(stdout);
}
int main()
{ int i,sol;
read();
SS=10001; // Super sursa
SD=10002; // Super destinatie
for(i=n;i>=1;--i)
    {
    // Adaugam legaturi intre super sursa si nodurile din multimea L
    add(SS,i,1);
    add(i,SS,0);
    }
for(i=1;i<=m;++i)
    {
    // Adaugam legaturi intre super destinatie si nodurile din multimea R
    add(n+i,SD,1);
    add(SD,n+i,0);
    }
solve();
sol=0;
constr_sol();
write();
return 0;
}