Cod sursa(job #720246)

Utilizator ioalexno1Alexandru Bunget ioalexno1 Data 22 martie 2012 14:59:07
Problema Cuplaj maxim in graf bipartit Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.89 kb
// Cuplaj maxim in graf bipartit realizat cu algoritmul lui Edmonds Karp
#include <cstdio>
#define N 10005
#define inf 1999999999
using namespace std;
struct nod{ int val; nod *urm; }*G[N];
int n,m,cap[N][N],flux[N][N],viz[N],tata[N],c[N],SS,SD,pas;
int sol,cx[N],cy[N];
void read()
{ int i,x,y,e;
  nod *aux;
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);
    aux=new nod; aux->val=y+n; aux->urm=G[x]; G[x]=aux;
    cap[x][y+n]=1;
    }
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&&cap[c[p]][aux->val]>flux[c[p]][aux->val])
                {
                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&&cap[aux->val][SD]>flux[aux->val][SD])
            {
            tata[SD]=aux->val; fm=inf;
            for(i=SD;i!=SS;i=tata[i])
                fm=min(fm,cap[tata[i]][i]-flux[tata[i]][i]);
            if(fm)
                {
                for(i=SD;i!=SS;i=tata[i])
                    {
                    flux[tata[i]][i]+=fm;
                    flux[i][tata[i]]-=fm;
                    }
                }
            }
    ++pas;
    }
}
void constr_sol()
{ int i,j,x;
  bool e;
for(i=1;i<=n;++i)
    {
    e=false; x=0;
    for(j=1;j<=m&&!e;++j)
        if(flux[i][j+n]==1)
                {
                e=true; x=j;
                }
    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;
  nod *aux;
read();
SS=10001; // Super sursa
SD=10002; // Super destinatie
for(i=1;i<=n;++i)
    {
    // Adaugam legaturi intre super sursa si nodurile din multimea L
    aux=new nod; aux->val=i; aux->urm=G[SS]; G[SS]=aux;
    aux=new nod; aux->val=SS; aux->urm=G[i]; G[i]=aux;
    cap[SS][i]=1;
    }
for(i=1;i<=m;++i)
    {
    // Adaugam legaturi intre super destinatie si nodurile din multimea R
    aux=new nod; aux->val=SD; aux->urm=G[n+i]; G[n+i]=aux;
    aux=new nod; aux->val=n+i; aux->urm=G[SD]; G[SD]=aux;
    cap[n+i][SD]=1;
    }
solve();
sol=0;
constr_sol();
write();
return 0;
}