Cod sursa(job #801858)

Utilizator costyv87Vlad Costin costyv87 Data 25 octombrie 2012 11:45:24
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include <cstdio>
#include <bitset>
#define df(x) (x->cap)-(x->fl)
using namespace std;
FILE *f,*g;

bitset <20100> bf;

struct nod{
     int cap,fl,y;
     nod *nxt,*alt;
     };
typedef nod* nd;
nd ax1,ax2,ax;
nd a[20100],ed[20100];
int q[20100],tt[20100];
int n,m,k,flow,p,mn;




inline void adauga(int x,int y)
{

     ax1=new(nod);
     ax2=new(nod);
     ax1->cap=1,ax2->cap=0;
     ax1->fl=0,ax2->fl=0;
     ax1->y=y, ax2->y=x;
     ax1->alt=ax2, ax2->alt=ax1;
     ax1->nxt=a[x], ax2->nxt=a[y];
     a[x]=ax1, a[y]=ax2;
}


void read()
{
     int x,y,i;

     fscanf(f,"%d%d%d",&n,&m,&k);
     p=n+m+1;
     for (i=1;i<=k;i++)
     {
          fscanf(f,"%d%d",&x,&y);
          adauga(x,y+n);
     }

     for (i=1;i<=n;i++)
          adauga(0,i);
     for (i=1;i<=m;i++)
          adauga(i+n,p);
}

inline int bfs()
{
     int i,j,nn,mm=-1;
     nd ax;

     bf.reset();
     q[bf[nn=0]=1]=0;

     for (i=0;i<=nn;i++)
     {
          if (q[i]==p) continue;

          for (ax=a[q[i]];ax;ax=ax->nxt)
          {
               if ( bf[ax->y]==0 && df(ax)>0 )
               {
                    bf[ax->y]=1;
                    ed[++mm]=ax;
                    tt[ax->y]=mm;
                    q[++nn]=ax->y;
               }

          }


     }



     return bf[n+m+1];
}

int main()
{
     f=fopen("cuplaj.in","r");
     g=fopen("cuplaj.out","w");

     read();
     while (bfs())
     {
          for (ax=a[p];ax;ax=ax->nxt)
          {

               if ( bf[ax->y]==0 || df(ax->alt)<=0) continue;


               for (mn=1,ax2=ed[tt[ax->y]];;ax2=ed[tt[ax2->alt->y]])
               {
                    mn=min(df(ax2),mn);
                    if (ax2->alt->y==0) break;
               }
               if (mn==0) continue;
               flow++;
               ax->alt->fl++;
               ax->fl--;
               for (mn=1,ax2=ed[tt[ax->y]];;ax2=ed[tt[ax2->alt->y]])
               {
                    ax2->fl++;
                    ax2->alt->fl--;
                    if (ax2->alt->y==0) break;
               }

          }
     }

     fprintf(g,"%d\n",flow);

     for (int i=1;i<=n;i++)
         for (ax=a[i];ax;ax=ax->nxt)
            if (ax->fl==1 && ax->cap==1)
                fprintf(g,"%d %d\n",i,ax->y-n);

     fclose(g);
     return 0;
}