https://loj.ac/problem/10077

题目描述

  给出一张n个节点m条边的无向连通图,求这张图的最短路数量。

思路

  我们可以直接进行DIjkstra,在进行最短路算法时,如果dis[u]由dis[v]转移过来,那么根据加法原理,到u的最短路数量ans[u]=ans[v],而对于相等最短路,加上可以转移过来的ans[v]即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=2e5+10,mod=100003;
int head[N],nxt[M<<1],to[M<<1],tot;
int dis[N],ans[N];
bool vis[N];
void add_edge(int x,int y)
{
    nxt[++tot]=head[x];
    head[x]=tot;
    to[tot]=y;
}
void Dijkstra()
{
    memset(dis,0x3f,sizeof(dis));
    priority_queue<pair<int,int> >q;
    dis[1]=0;ans[1]=1;q.push(make_pair(0,1));
    while(!q.empty())
    {
        int u=q.top().second;q.pop();
        if(vis[u])continue ;
        vis[u]=1;
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(dis[v]>dis[u]+1)
            {
                dis[v]=dis[u]+1;
                ans[v]=ans[u]%mod;
                q.push(make_pair(-dis[v],v));
            }
            else if(dis[v]==dis[u]+1)
                ans[v]=(ans[v]+ans[u])%mod;
        }
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add_edge(x,y);add_edge(y,x);
    }
    Dijkstra();
    for(int i=1;i<=n;i++)
        printf("%d\n",ans[i]);
    return 0;
}
02-12 14:51