D100 最短路条数 Dijkstra 算法 P1608 路径统计
D100 最短路条数 Dijkstra 算法 P1608 路径统计_哔哩哔哩_bilibili
给一个有权有向图(有重边),求 1 到 n 的最短路和最短路条数。统计条数要求经过的点的编号序列不同。
思路
首先,输入时需要去重边
主要看怎样统计最短路条数?
(1)如果 $d[v]>d[u]+w$,距离可以变短,那么最短路条数不增加,$cnt[v]=cnt[u]$
(2)如果 $d[v]=d[u]+w$,距离保持不变,那么最短路条数增加,$cnt[v]=cnt[v]+cnt[u]$
图中,4 到 6 的更新属于第(1)种,5 到 6 的更新属于第(2)种

相关板子:
D02【模板】最短路 Dijkstra 算法 P4779 单源最短路径 - 董晓 - 博客园
// 最短路条数 Dijkstra 算法 O(MlogN) #include<bits/stdc++.h> #define pii pair<int,int> using namespace std; const int N=2010,M=4e6; int h[N],to[M],ww[M],ne[M],idx; void add(int a,int b,int c){ to[++idx]=b,ww[idx]=c,ne[idx]=h[a],h[a]=idx; } int n,m,g[N][N]; int d[N],cnt[N]; bool vis[N]; void dijkstra(){ memset(d,0x3f,sizeof d); d[1]=0; cnt[1]=1; priority_queue<pii,vector<pii>,greater<pii> > q; q.push({0,1}); while(!q.empty()){ int u=q.top().second; q.pop(); if(vis[u])continue; vis[u]=1; for(int i=h[u];i;i=ne[i]){ int v=to[i],w=ww[i]; if(d[v]>d[u]+w){ //如果1到v的距离可以变小 d[v]=d[u]+w; cnt[v]=cnt[u]; //那就继承最短路条数 q.push({d[v],v}); } else if(d[v]==d[u]+w){ //如果1到v的距离相等 cnt[v]=cnt[v]+cnt[u]; //那就累加最短路条数 } } } } int main(){ scanf("%d%d",&n,&m); for(int i=1,a,b,c;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); if(g[a][b]==c) continue; //去重边 add(a,b,c); g[a][b]=c; } dijkstra(); if(d[n]==0x3f3f3f3f)printf("No answer\n"); else printf("%d %d\n",d[n],cnt[n]); }
给一个边权为 1 的无向图,求从 1 号点到其他点的最短路的条数
思路
本题不需要去重边。边权均为 1,最短路算法退化为 BFS
// 最短路条数 BFS 算法 O(n+m) #include<bits/stdc++.h> using namespace std; const int N=1e6+5,M=4e6+5,mod=100003; int h[N],to[M],ne[M],idx; void add(int a,int b){ to[++idx]=b,ne[idx]=h[a],h[a]=idx; } int n,m; int d[N],cnt[N]; void bfs(){ memset(d,0x3f,sizeof d); d[1]=0; cnt[1]=1; queue<int> q; q.push(1); while(!q.empty()){ int u=q.front();q.pop(); for(int i=h[u];i;i=ne[i]){ int v=to[i]; if(d[v]>d[u]+1){ d[v]=d[u]+1; cnt[v]=cnt[u]; q.push(v); } else if(d[v]==d[u]+1){ cnt[v]=(cnt[v]+cnt[u])%mod; } } } } int main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>n>>m; for(int i=0,a,b;i<m;i++){ cin>>a>>b; add(a,b),add(b,a); } bfs(); for(int i=1;i<=n;i++)cout<<cnt[i]<<"\n"; }
浙公网安备 33010602011771号