ENG  RUSTimus Online Judge
Online Judge
Problems
Authors
Online contests
About Online Judge
Frequently asked questions
Site news
Webboard
Links
Problem set
Submit solution
Judge status
Guide
Register
Update your info
Authors ranklist
Current contest
Scheduled contests
Past contests
Rules
back to board

Discussion of Problem 1076. Trash

KM algo. TLE on #3. Why? And please tell me the time complexity of KM.
Posted by Maigo Akisame 25 Jun 2004 14:43
program ural1076;
const
  maxn=150;
var
  w:array[1..maxn,1..maxn]of byte;
  g:array[1..maxn,1..maxn]of shortint;
    {0:not in the equal sub-graph;
     1:unmatched;
     -1:matched}
  lx,ly:array[1..maxn]of byte;
  s,t,cx,cy:set of 1..maxn;
  n,i,j:byte;
  total:longint;
function path(x:byte):boolean;
  var
    i,j:byte;
  begin
    path:=false;
    for i:=1 to n do
      if not (i in t) and (g[x,i]<>0) then begin
        t:=t+[i];
        if not (i in cy) then begin
          g[x,i]:=-g[x,i];
          cy:=cy+[i];
          path:=true;
          exit;
        end;
        j:=1;
        while (j<=n) and not (j in s) and (g[j,i]>=0) do inc(j);
        if j<=n then begin
          s:=s+[j];
          if path(j) then begin
            g[x,i]:=-g[x,i];g[j,i]:=-g[j,i];
            path:=true;
            exit;
          end;
        end;
      end;
  end;
procedure KM;
  var
    root,i,j,al:byte;
  begin
    fillchar(lx,sizeof(lx),0);
    fillchar(ly,sizeof(ly),0);
    for i:=1 to n do
      for j:=1 to n do
        if w[i,j]>lx[i] then lx[i]:=w[i,j];
    for i:=1 to n do
      for j:=1 to n do
        if lx[i]+ly[j]=w[i,j] then g[i,j]:=1 else g[i,j]:=0;
    root:=1;cx:=[];cy:=[];

    while root<=n do begin
      s:=[root];t:=[];
      if not (root in cx) then begin
        if path(root) then
          cx:=cx+[root]
        else begin
          al:=255;
          for i:=1 to n do
            for j:=1 to n do
              if (i in s) and not (j in t) then
                if lx[i]+ly[j]-w[i,j]<al then
                  al:=lx[i]+ly[j]-w[i,j];
          for i:=1 to n do
            if i in s then dec(lx[i],al);
          for i:=1 to n do
            if i in t then inc(ly[i],al);
          for i:=1 to n do
            for j:=1 to n do
              if lx[i]+ly[j]=w[i,j] then g[i,j]:=1 else g[i,j]:=0;
          cx:=[];cy:=[];
        end;
        root:=0;
      end;
      inc(root);
    end;
  end;
begin
  readln(n);
  for i:=1 to n do
    for j:=1 to n do
      read(w[i,j]);

  KM;

  total:=0;
  for i:=1 to n do
    for j:=1 to n do
      if g[i,j]>=0 then inc(total,w[i,j]);
  writeln(total);
end.