洛谷P1608 路径统计

@Pelom  October 12, 2021

题意

最短路计数

数据范围:$1 \le n \le 2000,0 \le m \le n(n-1)$

题解

在跑最短路的同时维护一个$cnt[i]$即可

  • 若能够更新$dis[v]$,则$cnt[v]=cnt[u]$
  • 若相等,则$cnt[v]+=cnt[u]$

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define mp make_pair
typedef pair<int,int> pii;
const int N=2000+10;
const int INF=0x3f3f3f3f;
int n,m,u,v,w;
int cnt;
int G[N][N],dis[N],ans[N];
inline void Dijkstra(){
    priority_queue<pii,vector<pii>,greater<pii> > pq;
    memset(dis,0x3f,sizeof(dis));
    pq.push(mp(0,1));
    dis[1]=0;
    ans[1]=1;
    for(;!pq.empty();){
        int d=pq.top().first,u=pq.top().second;
        pq.pop();
        if(dis[u]!=d)
            continue;
        for(int v=1;v<=n;v++){
            if(G[u][v]==INF)
                continue;
            if(dis[v]>d+G[u][v]){
                dis[v]=d+G[u][v];
                ans[v]=ans[u];
                pq.push(mp(dis[v],v));
            }
            else if(dis[v]==d+G[u][v])
                ans[v]+=ans[u];
        }
    }
}
int main(){
    memset(G,0x3f,sizeof(G));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);
        G[u][v]=min(G[u][v],w);
    }
    Dijkstra();
    if(dis[n]!=INF)
        printf("%d %d",dis[n],ans[n]);
    else puts("No answer");
    return 0;
}

添加新评论