最短路计数

题目描述

给出一个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。

思路

bfs;

代码实现

 1 #include<cstdio>
 2 const int mod=1e5+3;
 3 const int maxn=1e6+10;
 4 const int maxm=4e6+10;
 5 int n,m;
 6 int num[maxn];
 7 int h[maxn],hs;
 8 int et[maxm],en[maxm];
 9 void add(){
10     int a,b;
11     scanf("%d%d",&a,&b);
12     hs++,et[hs]=b,en[hs]=h[a],h[a]=hs;
13     hs++,et[hs]=a,en[hs]=h[b],h[b]=hs;
14 }
15 int q[maxn],head,tail;
16 int d[maxn];
17 void bfs(){
18     int a,b;
19     q[tail++]=num[1]=d[1]=1;
20     while(head<tail){
21         a=q[head++];
22         b=d[a]+1;
23         for(int i=h[a];i;i=en[i]){
24             if(!d[et[i]]) d[et[i]]=b,q[tail++]=et[i];
25             if(b==d[et[i]]) num[et[i]]+=num[a],num[et[i]]%=mod;
26         }
27     }
28 }
29 int main(){
30     scanf("%d%d",&n,&m);
31     for(int i=1;i<=m;i++) add();
32     bfs();
33     for(int i=1;i<=n;i++) printf("%d\n",num[i]);
34     return 0;
35 }

 

posted @ 2017-08-19 17:48  J_william  阅读(248)  评论(0编辑  收藏  举报