ENG  RUSTimus Online Judge
Online Judge
Задачи
Авторы
Соревнования
О системе
Часто задаваемые вопросы
Новости сайта
Форум
Ссылки
Архив задач
Отправить на проверку
Состояние проверки
Руководство
Регистрация
Исправить данные
Рейтинг авторов
Текущее соревнование
Расписание
Прошедшие соревнования
Правила
вернуться в форум

Обсуждение задачи 1076. Trash

KM algo. TLE on #3. Why? And please tell me the time complexity of KM.
Послано Maigo Akisame 25 июн 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.