upd:之前的博客什么也没讲,只贴了代码,居然能在百度搜素的第一条,我表示抱歉,,,,,,
考虑dijstra的过程,最短路计数我们只需要加上一个ans,如果当前能松弛,即dis[v]>dis[u]+e[i].w,我们就讲当前v的ans更新为ans[u],但还有一种特殊情况即dis[v]=dis[u]+e[i].w,我们此时需要将方案数累加,即ans[v]+=ans[u]
然后此题需要判断重边,就做完了
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define re register int #define ll long long #define inf 0x3f3f3f3f #define maxn 2000050 using namespace std; struct tu{ int u,v,w,nxt; }e[maxn<<1]; int head[maxn],cnt; void add(int u,int v,int w){ e[++cnt].u=u; e[cnt].v=v; e[cnt].w=w; e[cnt].nxt=head[u]; head[u]=cnt; } int chong[2005][2005]; int dis[maxn]; bool vis[maxn]; int n,m; ll ans[maxn]; priority_queue<pair<int,int> >q; void dijstra(){ memset(dis,inf,sizeof(dis)); dis[1]=0; ans[1]=1; q.push(make_pair(0,1)); while(q.size()){ int u=q.top().second; q.pop(); if(vis[u])continue; vis[u]=1; for(re i=head[u];i;i=e[i].nxt){ int v=e[i].v; if(dis[v]>dis[u]+e[i].w){ dis[v]=dis[u]+e[i].w; q.push(make_pair(-dis[v],v)); ans[v]=ans[u]; } else if(dis[v]==dis[u]+e[i].w){ ans[v]=ans[v]+ans[u]; } } } } signed main(){ scanf("%d%d",&n,&m); for(re i=1;i<=m;i++){ int a1,a2,a3; scanf("%d%d%d",&a1,&a2,&a3); if(!chong[a1][a2]) add(a1,a2,a3),chong[a1][a2]=cnt; else { if(e[chong[a1][a2]].w>a3)e[chong[a1][a2]].w=a3; } } dijstra(); if(dis[n]==inf)printf("No answer "); else printf("%d %lld ",dis[n],ans[n]); return 0; }