【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.