「3.2」最短路计数
问题背景
「一本通3.2 练习3」
题目描述
给出一个 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% 的数据,1≤N≤100000,0≤M≤200000。
#include<bits/stdc++.h>
using namespace std;
const int N=100003;
int n,m,dis[N],p=100003,ans[N],used[N];
vector<int> e[N];
void spfa(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
ans[1]=1;
used[1]=1;
deque<int>q;
q.push_back(1);
while(!q.empty()){
int x=q.front();
used[x]=0;
q.pop_front();
for(int i=0;i<e[x].size();i++){
int to=e[x][i];
if(dis[to]>dis[x]+1){
ans[to]=ans[x];
dis[to]=dis[x]+1;
if(!used[to]){
used[to]=1;
q.push_back(to);
}
}
else if(dis[to]==dis[x]+1){
ans[to]=(ans[to]+ans[x])%p;
}
}
}
for(int i=1;i<=n;i++)printf("%d\n",ans[i]%p);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
if(x==y)continue;
e[x].push_back(y);
e[y].push_back(x);
}
spfa();
}