这道题可以用各种算法踩掉,我选择的是SPFA。
因为题目要求计数,所以我们开一个ans数组表示数量。
分两种情况讨论:
一:dis_v>dis_u+1
最短路被更新了,可以直接ans_v=ans_u覆盖。
二:dis_v==dis_u+1
又找到一条最短路,将条数相加即可。
具体看代码:
#include<bits/stdc++.h> #define mod 100003 using namespace std; struct Edge { int to,next; }e[4500000]; int head[1200000],cnt; inline void adde(int u,int v){ e[++cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; } int n,m; //ans表示最短路条数 int dis[1200000],vis[1200000],ans[1200000]; queue<int>q; //稍加改动的SPFA inline void SPFA(){ memset(dis,0x3f,sizeof(dis)); q.push(1); dis[1]=0; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(dis[v]>dis[u]+1){ dis[v]=dis[u]+1; //最短路转移 ans[v]=ans[u]; if(!vis[v]){ vis[v]=1; q.push(v); } }else if(dis[v]==dis[u]+1){ //最短路统计 ans[v]=(ans[v]+ans[u])%mod; } } } } int main() { cin>>n>>m; for(int i=1;i<=m;i++){ int a,b; cin>>a>>b; adde(a,b); adde(b,a); } ans[1]=1;//记得初始化 SPFA(); for(int i=1;i<=n;i++){ cout<<ans[i]<<endl; } return 0; }