给出一个 N 个顶点 M 条边的无向无权图,顶点编号为 1∼N。问从顶点 1 开始,到其他每个点的最短路有几条。
输入格式
第一行包含 2 个正整数 N,M,为图的顶点数与边数。
接下来 M 行,每行 2 个正整数 x,y,表示有一条由顶点 x 连向顶点 y 的边,请注意可能有自环与重边。
输出格式
共 N 行,每行一个非负整数,第 i 行输出从顶点 1 到顶点 i 有多少条不同的最短路,由于答案有可能会很大,你只需要输出 ans mod100003 后的结果即可。如果无法到达顶点 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% 的数据,1≤N≤100;
对于 60% 的数据,1≤N≤103;
对于 100% 的数据,1≤N≤106,1≤M≤2×106。
分析spfa 同时记录次数
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
constexpr int maxn=0x7fffffff;
int n,m,dist[1000010],ans[1000010];
bool vis[1000010];
vector<int>adj[2000010];
void spfa(int x){
for(int i=1;i<=n;i++){
dist[i]=maxn;
}
queue<int>que;
que.push(x);
ans[x]=1;
vis[x]=1;
dist[x]=0;
while(!que.empty()){
int t=que.front();
que.pop();
vis[t]=0;
for(int y:adj[t]){
if(dist[y]>dist[t]+1) {
dist[y] = dist[t] + 1;
ans[y] = ans[t];
if (!vis[y]) {
vis[y] = 1;
que.push(y);
}
}
else if(dist[y]==dist[t]+1){
ans[y]=(ans[y]+ans[t])%100003;
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
adj[u].push_back(v);
adj[v].push_back(u);
}
spfa(1);
for(int i=1;i<=n;i++){
printf("%d\n",ans[i]);
}
}