最短路计数

P1144 最短路计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目描述

给出一个NN个顶点MM条边的无向无权图,顶点编号为1-N1N。问从顶点11开始,到其他每个点的最短路有几条。

输入格式

第一行包含22个正整数N,MN,M,为图的顶点数与边数。

接下来MM行,每行22个正整数x,yx,y,表示有一条顶点xx连向顶点yy的边,请注意可能有自环与重边。

输出格式

NN行,每行一个非负整数,第ii行输出从顶点11到顶点ii有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans \bmod 100003ansmod100003后的结果即可。如果无法到达顶点ii则输出00。

输入输出样例

输入 #1
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出 #1
1
1
1
2
4

说明/提示

11到55的最短路有44条,分别为22条1-2-4-51245和22条1-3-4-51345(由于4-545的边有22条)。

对于20\%20%的数据,N ≤ 100N100;

对于60\%60%的数据,N ≤ 1000N1000;

对于100\%100%的数据,N<=1000000,M<=2000000N<=1000000,M<=2000000。

dijkstra:

复制代码
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int n,m;
typedef pair<int,int> PAII;
const int N=1e7+10,M=2e7+10,mod=100003;
int h[N],e[M],ne[M],idx,cnt[N],dist[M];
bool st[N];
void add(int a,int b)
{
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}
void dijkstra(){
    memset(dist,0x3f,sizeof(dist));
    priority_queue<PAII,vector<PAII>,greater<PAII> >heap;
    dist[1]=0;
    heap.push({0,1});
    cnt[1]=1;
    while(heap.size())
    {
        auto t=heap.top();
        heap.pop();
        int dis=t.first,ver=t.second;
        if(st[ver]) continue;
        else st[ver]=true;
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[ver]+1)
            {
                dist[j]=dist[ver]+1;
                cnt[j]=cnt[ver];
                if(!st[j])
                {
                    heap.push({dist[j],j});
                }
            }
            else if(dist[j]==dist[ver]+1)
                cnt[j]=(cnt[j]+cnt[ver])%mod;
        }
        
    }
}
int main(){
    cin>>n>>m;
    memset(h,-1,sizeof(h));
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        add(a,b); 
        add(b,a);
    }
    dijkstra();
    for(int i=1;i<=n;i++)
        cout<<cnt[i]<<endl;
    return 0; 
}
复制代码

spfa

复制代码
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int n,m;
const int N=1e6+10,M=2e6,mod=100003;
int h[N],e[M],ne[M],idx,dist[N],cnt[N];
bool st[N];
void add(int a,int b)
{
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}
void spfa(int x)
{
    memset(dist,0x3f,sizeof(dist));
    dist[1]=0;
    queue<int> q;
    q.push(1);
    st[1]=true;
    cnt[1]=1;
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        st[t]=false;//防止队列里的元素重复
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[t]+1)
            {
                dist[j]=dist[t]+1;
                cnt[j]=cnt[t];//此时j-t相连,为同一条最短路径 
                if(!st[j])
                {
                    q.push(j);
                    st[j]=true;
                }
            }
            else if(dist[j]==dist[t]+1)
            {
                cnt[j]=(cnt[j]+cnt[t])%mod;
            }
        } 
    }
}
int main(){
    memset(h,-1,sizeof(h));
    cin>>n>>m;
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    spfa(1);
    for(int i=1;i<=n;i++)
        cout<<cnt[i]<<endl;
    return 0;
}
复制代码

 

posted @   小志61314  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示