Cod sursa(job #380391)

Utilizator philipPhilip philip Data 5 ianuarie 2010 22:48:15
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator fpc Status done
Runda Arhiva educationala Marime 2.43 kb
type muchie=^pmuchie;
     pmuchie=record
       inf:integer;
       adr,opus:muchie;
       av:boolean;
     end;

var i,n,m,e,x,y,flux:longint;
    a:array[0..20001] of muchie;
    viz:array[0..20001] of boolean;
    nou,p1,p2:muchie;
    ok,okk:boolean;
    bufin:array[1..65000] of byte;


procedure createedges(x,y:integer);
  begin
    new(nou);
    nou^.inf:=y;
    nou^.adr:=a[x];
    nou^.av:=true;
    a[x]:=nou;
    new(nou);
    nou^.inf:=x;
    nou^.adr:=a[y];
    nou^.av:=false;
    a[y]:=nou;
    a[x]^.opus:=a[y];
    a[y]^.opus:=a[x];
  end;

procedure sterge(x,y:integer);
  var p1:muchie;
  begin
    p1:=a[x];
    if a[x]^.inf=y then begin
      a[x]:=a[x]^.adr;
 //     dispose(p1);
    end else begin
      while p1^.adr^.inf<>y do p1:=p1^.adr;
      p1^.adr:=p1^.adr^.adr;
  //    dispose(p2);
    end;
    p1:=a[y];
    if a[y]^.inf=x then begin
      a[y]:=a[y]^.adr;
 //     dispose(p1);
    end else begin
      while p1^.adr^.inf<>x do p1:=p1^.adr;
      p1^.adr:=p1^.adr^.adr;
//      dispose(p2);
    end;
  end;

procedure dfs(k:integer);
  var p1:muchie;
  begin
    viz[k]:=true;
    if k=n+m+1 then begin
        flux:=flux+1;
        ok:=true;
        viz[k]:=false;
        okk:=true;
        exit;
    end else begin
        p1:=a[k];
        while p1<>nil do begin
          if (p1^.av) and (not viz[p1^.inf]) then dfs(p1^.inf);
          if ok then begin
            p1^.av:=false;
            p1^.opus^.av:=true;
            if k<>0 then exit
             else begin
               ok:=false;
               sterge(k,p1^.inf);
             end;
          end;
          p1:=p1^.adr;
        end;
      end;
  end;

begin
  assign(input,'cuplaj.in');
  reset(input);
  assign(output,'cuplaj.out');
  rewrite(output);
  settextbuf(input,bufin);
  readln(n,m,e);
  for i:=1 to e do begin
    readln(x,y);
    y:=n+y;
    createedges(x,y);
  end;

  for i:=1 to n do if a[i]<>nil then createedges(0,i);
  for i:=n+1 to n+m do if a[i]<>nil then createedges(i,n+m+1);

  viz[n+m+1]:=true;
  okk:=true;
  while okk do begin
    okk:=false;
    fillchar(viz,n+m+2,false);
    ok:=false;
    dfs(0);
  end;

  writeln(flux);
  for i:=1 to n do begin
    p1:=a[i];
    while p1<>nil do begin
      if (p1^.opus^.av) and (p1^.inf<>0) then writeln(i,' ',p1^.inf-n);
      p1:=p1^.adr;
    end;
  end;
  close(input);
  close(output);

end.