ASSIGN1 - Phân công hoàn thành sớm nhất

Tác giả: khuc_tuan

Ngôn ngữ: Pascal

Uses math;
Const     inp = '';
          out = '';
          maxn = 1001;

Var       n,res,c    : longint;
          a    : array [1..maxn,1..maxn] of longint;
          mx,my,queue,trace  :     array [1..maxn] of longint;

procedure nhap;
var i,j : longint;
  begin
      assign(input,inp); reset(input);
      assign(output,out); rewrite(output);
      readln(n);
      for i := 1 to n do
        for j := 1 to n do
          begin
            read(a[i,j]);
            c := max(c,a[i,j]);
          end;
  end;

procedure khoitao(x : longint);
var i,j : longint;
  begin
      fillchar(mx,sizeof(mx),0);
      fillchar(my,sizeof(my),0);
      for i := 1 to n do
        for j := 1 to n do
          if (a[i,j]<=x) and (my[j]=0) then
            begin
                my[j] := i; mx[i] := j;
                break;
            end;
  end;

function timduongmo(x : longint) : longint;
var i,j,left,right : longint;
   begin
       fillchar(trace,sizeof(trace),0);
       left := 0; right := 0;
       for i := 1 to n do
         if mx[i]=0 then
           begin
               inc(right); queue[right] := i;
           end;
       while left < right do
         begin
             inc(left); i := queue[left];
             for j := 1 to n do
               if (a[i,j]<=x) and (trace[j]=0) then
                 begin
                     trace[j] := i;
                     if my[j]=0 then exit(j);
                     inc(right); queue[right] := my[j];
                 end;
         end;
       exit(0);
   end;

procedure morong(f : longint);
var next,x : longint;
  begin
      repeat
         x := trace[f];
         next := mx[x];
         mx[x] := f;
         my[f] := x;
         f := next;
      until f=0;
  end;

function check(x : longint) : boolean;
var i,j,f,dem : longint;
  begin
      khoitao(x);
      repeat
         f := timduongmo(x);
         if f = 0 then break;
         morong(f);
      until false;
      dem := 0;
      for i := 1 to n do
        if mx[i]<>0 then inc(dem);
      if dem=n then exit(true) else exit(false);
  end;

procedure main;
var d,mid : longint;
  begin
      d := 0;
      while d <= c do
        begin
          mid := (d+c) shr 1;
          if check(mid) then
            begin
                res := mid;
                c := mid-1;
            end
          else d := mid+1;
        end;
      writeln(res);
  end;

begin
    nhap;
    main;
end.


Download