最短路计数
题目描述
给出一个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<tail do
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.