9.9 极其简单的最短路问题 2721

  • 题目
  • 题解
  • 代码

题目

小C终于被小X感动了,于是决定与他看电影,然而小X距离电影院非常远,现在假设每条道路需要花费小X的时间为1,由于有数以万计的好朋友沿路祝贺,导致小X在通过某些路不得不耗费1的时间来和他们聊天,尽管他希望尽早见到小C,所以他希望找到一条最快时间到达电影院的路。
一开始小X在1号点,共有N个点,M条路,电影院为T号点。

30%:n<=10 m<=20
60%: n<=1000 m<=20000
100%: n<=5000000 m<=10000000

题解

好的,用spfa就很好,因为出题人好心的把最大的3个测试点开到了10s
时间复杂度O(ve)

不过据说原版题目spfa会炸,那么怎么办呢?
由于观察到边权只会是1或2,可以将其拆2的边为1和1,然后直接用bfs即可,复杂度为O(n+m)————
话说你不会忘了bfs怎么打吧?

代码

const
  max=20000000;
var
  n,m,t,i,j,k,x,z:longint;
  ls,d:array[0..5000000]of longint;
  ne,y,w:array[0..20000000]of longint;
  v:array[0..20000000]of longint;
   b:array[0..5000000]of boolean;

procedure spfa;
var
  i,k,h,t,x,z:longint;
begin
  h:=0;t:=1;v[1]:=1;b[1]:=true;d[1]:=0;
  while hdo
    begin
      inc(h);
      k:=ls[v[h mod max]];
      while k>0 do
        begin
          x:=v[h mod max];
          if d[y[k]]=0 then d[y[k]]:=maxlongint;
          if d[x]+w[k]then
            begin
              d[y[k]]:=d[x]+w[k];
              if not b[y[k]] then
                begin
                  b[y[k]]:=true;
                  inc(t);
                  v[t mod max]:=y[k];
                end;
            end;
          k:=ne[k];
        end;
      b[v[h mod max]]:=false;
    end;
end;

begin
  readln(n,m,t);
  for i:=1 to m do
    begin
      readln(x,k,z);
      inc(j);
      y[j]:=k;w[j]:=z;ne[j]:=ls[x];ls[x]:=j;
      inc(j);
      y[j]:=x;w[j]:=z;ne[j]:=ls[k];ls[k]:=j;
    end;
  spfa;
  writeln(d[t]);
end.


你可能感兴趣的:(spfa,广度优先搜索)