题目描述
给出一个N个顶点M条边的无向无权图,顶点编号为1~N。问从顶点1开始,到其他每个点的最短路有几条。
输入输出格式
输入格式:
输入第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式:
输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。
输入输出样例
输入样例#1:
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出样例#1:
1
1
1
2
4
说明
1到5的最短路有4条,分别为2条1-2-4-5和2条1-3-4-5(由于4-5的边有2条)。
对于20%的数据,N ≤ 100;
对于60%的数据,N ≤ 1000;
对于100%的数据,N<=1000000,M<=2000000。
做法:spfa模板
代码如下:
const
maxn=4000000;
type
rec=record
x,y,next:longint;
end;
var
g:array[1..maxn]of rec;
list,ls:array[1..maxn div 2]of longint;
dis,ans:array[1..maxn div 2]of int64;
v:array[1..maxn div 2]of boolean;
n,m:longint;
procedure cin(i,j,k:longint);
begin
with g[k] do
begin
x:=i; y:=j;
next:=ls[x];
ls[x]:=k;
end;
end;
procedure init;
var
i,k,q,p:longint;
begin
k:=0;
readln(n,m);
for i:=1 to m do
begin
inc(k);
readln(p,q);
cin(p,q,k);
inc(k);
cin(q,p,k);
end;
end;
procedure spfa;
var
head,tail,t:longint;
begin
head:=0;
tail:=1;
ans[1]:=1;
dis[1]:=1;
list[1]:=1;
while head<tail do
begin
inc(head);
t:=ls[list[head]];
while t>0 do
with g[t] do
begin
if ans[y]=0 then
begin
v[y]:=true;
ans[y]:=ans[x];
dis[y]:=(dis[x]+1) mod 100003;
inc(tail);
list[tail]:=y;
end
else if dis[x]+1=dis[y] then ans[y]:=(ans[x]+ans[y]) mod 100003;
t:=next;
end;
v[list[head]]:=false;
end;
end;
procedure print;
var
i:longint;
begin
for i:=1 to n do
writeln(ans[i]);
end;
begin
init;
spfa;
print;
end.