Cod sursa(job #302583)

Utilizator adrianraduleaRadulea Adrian adrianradulea Data 9 aprilie 2009 00:50:20
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include<stdio.h>
FILE *f,*g;
long n,m,e,liber,t[5][200000],x,i,y,c[200000],fin[200000],z,viz[20000],parinte[20000],min,p,fluxm;
int df(long k)
{ long p=c[k]; viz[k]=1;
  while(p!=0)
   { if(!parinte[t[1][p]]&&t[3][p]&&!viz[t[1][p]]) { parinte[t[1][p]]=k; df(t[1][p]); }
     p=t[2][p];
   }
  if(parinte[n+m+2]) return 1; return 0;
}
void init()
{ liber=1;
  for(i=1;i<=e;i++)
   { fscanf(f,"%ld%ld",&x,&y);
     x++; y=n+1+y;
     if(!c[x]) { c[x]=liber; t[1][liber]=y; t[3][liber]=1; fin[x]=liber; liber++; }
     else { t[2][fin[x]]=liber; t[1][liber]=y; t[3][liber]=1; fin[x]=liber; liber++; }
     z=x; x=y ;y=z;
     if(!c[x]) { c[x]=liber; t[1][liber]=y; fin[x]=liber; liber++; }
     else { t[2][fin[x]]=liber; t[1][liber]=y; fin[x]=liber; liber++; }
   }
  for(i=2;i<=n+1;i++)
   { x=1; y=i;
     if(!c[x]) { c[x]=liber; t[1][liber]=y; t[3][liber]=1; fin[x]=liber; liber++; }
     else { t[2][fin[x]]=liber; t[1][liber]=y; t[3][liber]=1; fin[x]=liber; liber++; }
     z=x; x=y ;y=z;
     if(!c[x]) { c[x]=liber; t[1][liber]=y; fin[x]=liber; liber++; }
     else { t[2][fin[x]]=liber; t[1][liber]=y; fin[x]=liber; liber++; }
   }
  for(i=n+2;i<=n+m+1;i++)
   { x=i; y=n+m+2;
     if(!c[x]) { c[x]=liber; t[1][liber]=y; t[3][liber]=1; fin[x]=liber; liber++; }
     else { t[2][fin[x]]=liber; t[1][liber]=y; t[3][liber]=1; fin[x]=liber; liber++; }
     z=x; x=y ;y=z;
     if(!c[x]) { c[x]=liber; t[1][liber]=y; fin[x]=liber; liber++; }
     else { t[2][fin[x]]=liber; t[1][liber]=y; fin[x]=liber; liber++; }
   }
}
int main()
{ f=fopen("cuplaj.in","r"); g=fopen("cuplaj.out","w");
  fscanf(f,"%ld%ld%ld",&n,&m,&e);
  init();
  while(df(1))
   { min=1000000; x=n+m+2;
     while(x!=1)
      { p=c[parinte[x]];
	while(t[2][p]!=0)
	 { if(t[1][p]==x) if(t[3][p]<min) min=t[3][p];
	   p=t[2][p];
	 }
	x=parinte[x];
      }
     x=n+m+2; fluxm+=min;
     while(parinte[x])
      { p=c[parinte[x]];
	while(p)
	 { if(t[1][p]==x) t[3][p]-=min;
	   p=t[2][p];
	 }
	p=c[x];
	while(p)
	 { if(t[1][p]==parinte[x]) { t[3][p]+=min; }
	   p=t[2][p];
	 }
	x=parinte[x];
      }
     for(i=1;i<=n+m+2;i++) { parinte[i]=0; viz[i]=0; }
   }
  fprintf(g,"%ld\n",fluxm);
  for(i=2;i<=n+1;i++)
   { p=c[i];
     while(p!=0)
      { if(t[1][p]!=1&&t[3][p]==0)
	  fprintf(g,"%ld %ld\n",i-1,t[1][p]-1-n);
	p=t[2][p];
      }
   }
  fclose(g);
  return 0;
}