洛谷P1144 最短路计数(spfa)

最短路计数

题目描述

给出一个N个顶点M条边的无向无权图,顶点编号为1~N。问从顶点1开始,到其他每个点的最短路有几条。

输入输出格式

输入格式:

输入第一行包含2个正整数N,M,为图的顶点数与边数。

接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。

输出格式:

输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。

分析:第一次到达这个点时的距离就是最短距离,之后走不同的路若有相等的距离方案数就为两个之和。

代码

const
  maxn=2000000;
var
  x,y,ls,list,ans,next,dis:array[0..maxn] of longint;
  v:array[0..maxn] of boolean;
  i,j,n,m,k,x1,y1:longint;


procedure init(p,q,s:longint);
begin
  next[s]:=ls[p];
  ls[p]:=s;
  x[s]:=p;
  y[s]:=q;
end;


procedure spfa;
var
  head,tail,t:longint;
begin
  head:=0;
  tail:=1;
  list[1]:=1;
  ans[1]:=1;
  dis[1]:=1;
  while head     begin
      inc(head);
      t:=ls[list[head]];
      while t>0 do
        begin
          if ans[y[t]]=0 then
            begin
              v[y[t]]:=true;
              ans[y[t]]:=ans[x[t]];
              dis[y[t]]:=(dis[x[t]]+1) mod 100003;
              inc(tail);
              list[tail]:=y[t];
            end
          else if dis[x[t]]+1=dis[y[t]] then ans[y[t]]:=(ans[y[t]]+ans[x[t]]) mod 100003;
          t:=next[t];
        end;
      v[list[head]]:=false;
    end;
end;


begin
  readln(n,m);
  for i:=1 to m do
    begin
      inc(k);
      readln(x1,y1);
      init(x1,y1,k);
      inc(k);
      init(y1,x1,k);
    end;
  spfa;
  for i:=1 to n do
    writeln(ans[i]);
end.


你可能感兴趣的:(图论,最短路,spfa)