【裸SPFA】星门跳跃

题目:星门跳跃

问题编号:341

题目描述

在EVE游戏中,宇宙被划分成为许多区域,每个区域中都有数目不定的星门,可以通过星门来跳跃到特定的区域(星门是双向的)。
现在你正参与BBE联军与MLGBD联盟的会战,但由于飞船受损,需要尽快回到后方的友军空间站进行维护。
试编写程序,计算出所须的最短的返回空间站时间。
为了简化问题,我们约定飞船所在的位置为区域1,空间站所在的位置为区域N。

问题规模:
对于80%的数据,1<N<=10000,1<M<50000;
对于100%的数据,1<N<=30000,1<M<150000,1<=X[],Y[]<=N,1<=Z[]<=4096;

输入格式

第1行,两个整数N,M,分别为区域的总数和星门的总数;
第2..M+1行,每行三个整数X[i],Y[i],Z[i],分别为星门连接的两个区域,以及跳跃所需时间;

输出格式

一个整数,返回空间站所需的最短时间。

样例输入

样例一
5 3
1 4 5
4 5 1
1 2 7

样例二
10 11
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
1 5 7
6 9 3

 

样例输出

样例一
6

样例二
28

=================

裸的SPFA

========================

type
  pnode=^node;
  node=record
         x,t:longint;
         next:pnode;
       end;
var
  n,m:longint;
  ti:array[1..30000]of pnode;
  dis:array[1..30000]of longint;
  f_bo:array[1..30000]of boolean;
  h:array[1..200000]of longint;
procedure init;
begin
  assign(input,'rq341.in');
  assign(output,'rq341.out');
  reset(input); rewrite(output);
end;

procedure terminate;
begin
  close(input); close(output);
  halt;
end;

procedure insert(x,y,t:longint);
var
  p:pnode;
begin
  new(p);
  p^.t:=t; p^.x:=y;
  p^.next:=ti[x]; ti[x]:=p;
end;

procedure spfa;
var
  l,r:longint;
  x:longint;
  p:pnode;
begin
  fillchar(dis,sizeof(dis),$7);
  fillchar(f_bo,sizeof(f_bo),true);
  dis[1]:=0;
  f_bo[1]:=false;
  l:=0; r:=1;
  h[r]:=1;
  repeat
    inc(l);
    x:=h[l];
    p:=ti[x];
    while p<>nil do
      begin
        if dis[x]+p^.t<dis[p^.x] then
          begin
            dis[p^.x]:=dis[x]+p^.t;
            if f_bo[p^.x] then
              begin
                inc(r);
                h[r]:=p^.x;
                f_bo[p^.x]:=false;
              end;
          end;
        f_bo[x]:=true;
        p:=p^.next;
      end;
  until l>=r;
  writeln(dis[n]);
end;

procedure main;
var
  i:longint;
  x,y,t:longint;
begin
  readln(n,m);
  for i:=1 to n do ti[i]:=nil;
  for i:=1 to m do
    begin
      readln(x,y,t);
      insert(x,y,t);
      insert(y,x,t);
    end;
  spfa;
end;

begin
  init;
  main;
  terminate;
end.


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值