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