【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.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值