Cod sursa(job #405756)

Utilizator nickyyLal Daniel Emanuel nickyy Data 28 februarie 2010 18:32:38
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator fpc Status done
Runda Arhiva educationala Marime 2.2 kb
const infile='cuplaj.in';
  outfile='cuplaj.out';
  maxn=10001;
  inf=maxlongint;
type adresa=^pnod;
  pnod=record  nod:longint; next:adresa; end;
  coada=record prim,ultim:adresa; end;
var a:array[0..maxn]of adresa;
  L,R,dist:array[0..maxn]of longint;
  Q:coada;
  n,m,e,cuplaj:longint;

 procedure citire;
 var i,j:longint;
   p:adresa;
 begin
   assign(input,infile); reset(input); readln(n,m,e);
   while(e>0)do begin
     readln(i,j); dec(e);
     new(p); p^.nod:=j; p^.next:=a[i]; a[i]:=p;
     end;
   close(input);
 end;

 procedure push(x:longint);
 var p:adresa;
 begin
   new(p); p^.nod:=x; p^.next:=nil;
   if(Q.prim=nil)then begin Q.prim:=p; Q.ultim:=p; end
   else begin
     Q.ultim^.next:=p; Q.ultim:=p;
     end;
 end;

 function pop:integer;
 var p:adresa;
 begin
   p:=Q.prim; pop:=p^.nod;
   Q.prim:=p^.next;
   dispose(p);
 end;

 function bf:boolean;
 var v:longint;
   p:adresa;
 begin
   for v:=1 to n do
     if(L[v]=0)then begin
       dist[v]:=0; push(v);
       end
     else dist[v]:=inf;
   dist[0]:=inf;
   while(Q.prim<>nil)do begin
       v:=pop; p:=a[v];
       while(p<>nil)do begin
         if(dist[R[p^.nod]]=inf)then begin
           dist[R[p^.nod]]:=dist[v]+1;
           if(R[p^.nod]<>0)then push(R[p^.nod]);
           end;
         p:=p^.next;
         end;
       end;
   bf:=(dist[0]<>inf);
 end;

 function df(v:longint):boolean;
 var p:adresa;
 begin
   if(v<>0)then begin
     p:=a[v];
     while(p<>nil)do begin
       if(dist[R[p^.nod]]=dist[v]+1)then
         if df(R[p^.nod]) then begin
           R[p^.nod]:=v;
           L[v]:=p^.nod;
           df:=true; exit;
           end;
       p:=p^.next;
       end;
     end
   else begin df:=true; exit; end;
   dist[v]:=inf;
   df:=false;
 end;

 procedure HopcroftKarp;
 var v:longint;
 begin
   cuplaj:=0;
   while bf do
     for v:=1 to n do
       if(L[v]=0)then
         if df(v) then inc(cuplaj);
 end;

 procedure afisare;
 var v:longint;
 begin
   assign(output,outfile); rewrite(output);
   writeln(cuplaj);
   for v:=1 to n do if(L[v]<>0)then writeln(v,' ',L[v]);
   close(output);
 end;

begin
  citire; HopcroftKarp; afisare;
end.