【问题描述】 给出一个 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解释】
1 到 5 的最短路有 4 条,分别为 2 条 1−2−4−5 和 2 条 1−3−4−5(由于 4−5 的边有 2 条)。
【数据范围及约定】
对于 20% 的数据,N≤100;
对于 60% 的数据,N≤1000;
对于 100% 的数据,N≤100000,M≤200000。
#include<iostream>
#include<iomanip>
#include<vector>
#include<queue>
#include<deque>
using namespace std;
const long long N=100005,INF=1e9;
long long s,t,n,m,x,y,vis[N],fs[N],dis[N];
//dis:起点到点最短长度,vis:最短长度是否已经确定
//v:点编号,w:权值
struct quan{
long long v,w;
bool operator<(const quan a) const{return w<a.w;}
};
struct bian{
long long v,w;
};
vector<bian> e[N];
priority_queue<quan> pq;
void Dijkstra(){
while(pq.size()){
long long u=pq.top().v;
pq.pop();
if(vis[u]) continue;
vis[u]=1;
for(auto ed:e[u]){
long long v=ed.v;
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
fs[v]=fs[u];
fs[v]%=100003;
pq.push({v,dis[v]});
}
else if(dis[v]==dis[u]+1){
fs[v]+=fs[u];
fs[u]=fs[v];
fs[v]%=100003;
fs[u]%=100003;
}
}
}
}
int main(){
cin>>n>>m;
for(long long i=1;i<=m;i++){
cin>>x>>y;//输入建图
e[x].push_back({y,1});
e[y].push_back({x,1});
}
for(long long i=1;i<=n;i++) dis[i]=INF,fs[i]=0,vis[i]=0;//初始化
dis[1]=0;
pq.push({1,0});
fs[1]=1;
Dijkstra();
for(int i=1;i<=n;i++){
cout<<fs[i]%100003<<"\n";
}
return 0;
}