【CodeVS4019】想越獄的黎恆健

【Description】

  這次黎恆健來到了經典美劇《越獄》的場景裏……
  他被抓起來了(-.-幹嘛幻想這麼鬱悶的場景……)。
  黎恆健身爲新一代的Scofield,在挖了半個月之後終於挖通牢房裏的地道。
  在地道里,無數的管道路線困惑了他。(若對情節有任何疑問,請觀看原劇)
  黎恆健看了看自己的紋身,明白了整個管道網是由N個小房間和若干小房間之間的單向的管道組成的。
  小房間編號爲不超過N的正整數。
  對於某個管道,黎恆健只能在人品不超過一定程度時通過。
  黎恆健一開始在房間1,現在黎恆健想知道,每個小房間他最多能夠以人品多少的狀態到達。
  注意,黎恆健的人品在出發以後是不會改變的。


【Input】

  每組測試數據的第一行有一個正整數N(1<=N<=2000)。
  接下來若干行描述管道,每行三個正整數A,B,R(1<=A,B<=N),表示A房間有一條到達B房間的管道,且黎恆健的人品不超過R時可以通過(注意從B房間不可由此管道到達A房間,即管道是單向的)
  整個輸入數據以一行0 0 0結束
  特別地,對於30%的數據,有N<=100
  表示A房間有一條到達B房間的管道,且黎恆健的人品不超過R時可以通過(注意從B房間不可由此管道到達A房間,


【Output】

  對每組測試數據輸出N-1行,分別表示對於2到N號的小房間,黎恆健最多能夠以人品多少的狀態到達。


【Sample Input】

4
1 2 30
1 3 20
2 3 25
3 4 30
2 4 20
0 0 0

【Sample Output】

30
25
25

【題解】

  讀完題目只要搞清一點就好了:
  對於每個房間的最大人品 rp[i]  滿足
  rp[i]=max{min{rp[k],limit(i,k)}}for each(i,k) in E

const maxe=4000010;
type struct = record
                go,next,val:longint;
              end;
var n,cnt:longint;
    edge:array[0..maxe] of struct;
    en:array[0..2010] of longint;
    team:array[0..maxe] of longint;
    used:array[0..2010] of boolean;
    dist:array[0..2010] of longint;
function min(x,y:longint):longint;
  begin if x<y then exit(x) else exit(y); end;
procedure addedge(u,v,r:longint);  //前向星加邊
  begin
    inc(cnt); edge[cnt].go:=v; edge[cnt].val:=r;
    edge[cnt].next:=en[u]; en[u]:=cnt;
  end;
procedure init;  //讀入
  var i,a,b,r:longint;
  begin
    readln(n); cnt:=0;
    readln(a,b,r);
    while (a<>0) or (b<>0) or (r<>0) do begin
      addedge(a,b,r);
      readln(a,b,r);
    end;
  end;
procedure main;  //廣搜
  var head,tail,now,tmp,i,tt:longint;
  begin
    head:=0; tail:=1; team[1]:=1;
    dist[1]:=maxlongint;
    for i:=2 to n do dist[i]:=0;
    while head<>tail do begin
      head:=(head+1) mod maxe; now:=team[head];
      i:=en[now];
      while i<>0 do begin
        tmp:=edge[i].go;
        tt:=min(dist[now],edge[i].val);
        if dist[tmp]<tt then begin
          dist[tmp]:=tt;
          if not used[tmp] then begin
            inc(tail); team[tail]:=tmp; used[tmp]:=true;
          end;
        end;
        i:=edge[i].next;
      end;
      used[now]:=false;
    end;
  end;
procedure print;  //輸出
  var i:longint;
  begin
    for i:=2 to n do writeln(dist[i]);
  end; 
begin
  init;
  main;
  print;
end.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章