题目描述
给出一个N个顶点M条边的无向无权图,顶点编号为1-N。问从顶点1开始,到其他每个点的最短路有几条。
输入格式
第一行包含22个正整数N,MN,M,为图的顶点数与边数。
接下来MM行,每行22个正整数x,yx,y,表示有一条顶点xx连向顶点yy的边,请注意可能有自环与重边。
输出格式
共N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans mod 100003后的结果即可。如果无法到达顶点i则输出00。
输入输出样例
输入 #1复制
5 7 1 2 1 3 2 4 3 4 2 3 4 5 4 5输出 #1复制
1 1 1 2 4说明/提示
11到55的最短路有4条,分别为2条1−2−4−5和22条1−3−4−5(由于4−5的边有2条)。
对于20\%20%的数据,N ≤ 100;
对于60\%60%的数据,N ≤ 1000;
对于100\%100%的数据,N<=1000000,M<=2000000。
由于是无权图,最短距离可由bfs第一次搜到求出
代码:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N=1000000,M=2000000,mod=100003;
int h[N],e[M],ne[M],ans[N],dist[N],idx; //链式前向星
int n,m;
void add(int u,int v)
{
e[idx]=v,ne[idx]=h[u],h[u]=idx++;
}
void bfs()
{
ans[1]=1;dist[1]=1;
queue<int> q;
q.push(1);
while(q.size())
{
int t=q.front();
q.pop();
for(int i=h[t];i!=-1;i=ne[i])
{
int j=e[i];
if(!dist[j]) {dist[j]=dist[t]+1;q.push(j);} //第一次搜到更新最短距离
if(dist[j]==dist[t]+1) ans[j]=(ans[t]+ans[j])%mod; //由最短点搜到更新答案数组
}
}
}
int main()
{
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--){
int a,b;
scanf("%d%d",&a,&b);
if(a!=b) {add(a,b);add(b,a);}
}
bfs();
for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
return 0;
}