基本思想:
- 对于任意点,从源点到这个点的最短路径数量可以由直接到达这个点并更新这个点dis的点的最短路径直接推出。通过归纳法可知,当dis相同时直接累加最短路径方案数,dis小于时直接继承上一点的方案数即可.
易错点:
- 不能把=打成-.
- 重载<运算符时需要相反.
- 使用dijkstra之前需要初始化dis[]数组.
- 使用dijkstra之前需要初始化dis[s]为0.
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN=2e6,MAXM=4e6,MOD=100003;
struct Edge{
int from,to,w,nxt;
}e[MAXM];
int head[MAXN],edgeCnt=1;
void addEdge(int u,int v,int w){
e[++edgeCnt].from=u;
e[edgeCnt].to=v;
e[edgeCnt].w=w;
e[edgeCnt].nxt=head[u];
head[u]=edgeCnt;
}
struct Node{
int nowU,dis;
bool operator <(Node another)const{
return dis>another.dis;
}
};
int dis[MAXN],cnt[MAXN];
int s=1;
void dijkstra(){
memset(dis,0x3f,sizeof(dis));
priority_queue<Node> q;
q.push(Node{s,0});
dis[s]=0;
cnt[s]=1;
while(!q.empty()){
Node nowNode=q.top();
q.pop();
int nowU=nowNode.nowU,nowDis=nowNode.dis;
if(nowDis>dis[nowU])continue;
for(int i=head[nowU];i;i=e[i].nxt){
int nowV=e[i].to;
if(dis[nowV]>dis[nowU]+e[i].w){
dis[nowV]=dis[nowU]+e[i].w;
q.push(Node{nowV,dis[nowV]});
cnt[nowV]=cnt[nowU];
}else if(dis[nowV]==dis[nowU]+e[i].w){
cnt[nowV]+=cnt[nowU];
cnt[nowV]%=MOD;
}
}
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v,1);
addEdge(v,u,1);
}
dijkstra();
for(int i=1;i<=n;i++){
printf("%d\n",cnt[i]);
}
return 0;
}