洛谷P1144

最短路计数

题目描述

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

输入格式

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

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

输出格式

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

样例 #1

样例输入 #1

5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5

样例输出 #1

1
1
1
2
4

提示

15 的最短路有 4 条,分别为 2124521345(由于 45 的边有 2 条)。

对于 20% 的数据,1N100
对于 60% 的数据,1N103
对于 100% 的数据,1N1061M2×106


1、因为边权是1所以bfs,spfa,dijkstra都可以因为spfa最近在学习所以而且spfa打起来挺顺手的,就用spfa打的

2、我们用一个数组记录每个点最短路的答案

3、这里自环和重边不要用考虑,因为前向星中存的边会跑完,重边会跑两遍,这样的话不会影响计数的,举个例子就是

1 2
1 2
1 2

这里答案会输出1 2,因为1到2有两条边会都会跑所以最短路有两条

4、我们考虑ans的更新。采用分类讨论。

if(d[j] > d[t] + 1)
            {
                d[j] = d[t] + 1;
                ans[j] = ans[t] % mod;
                if(!inq[j])
                {
                    inq[j] = 1;
                    q.push(j);
                }
            }
            else if(d[j] == d[t] + 1)    
            ans[j] =(ans[j] + ans[t]) % mod;

5、注意答案要边计算边取模

6、注意要初始化链表啊,表头最开始全部初始化为 -1


#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

const int N = 1e6 + 10, M = 2e6 + 10, mod = 100003;

int n, m, ans[N];

int h[N], e[M], ne[M], idx;
void add(int a, int b)
{
    e[idx] = b; ne[idx] = h[a]; h[a] = idx ++;
}

int d[N];
bool inq[N];
void spfa()
{
    queue<int> q;
    for(int i = 1; i <= n; ++ i)    d[i] = 0x7fffffff;
    memset(inq, 0, sizeof inq);
    d[1] = 0; q.push(1); inq[1] = 1; ans[1] = 1;
    while(q.size())
    {
        auto t = q.front(); q.pop(); inq[t] = 0;
        for(int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if(d[j] > d[t] + 1)
            {
                d[j] = d[t] + 1;
                ans[j] = ans[t] % mod;
                if(!inq[j])
                {
                    inq[j] = 1;
                    q.push(j);
                }
            }
            else if(d[j] == d[t] + 1)    
            ans[j] =(ans[j] + ans[t]) % mod;
        }
    } 
}
int main()
{
    freopen("1.txt","r",stdin);
    memset(h, -1, sizeof h);
    cin >> n >> m;
    for(int i = 1; i <= m; ++ i)
    {
        int a, b; cin >> a >> b;
        add(a, b);add(b, a);
    }
    spfa();
    for(int i = 1; i <= n; ++ i)    cout << ans[i] << endl;
    return 0;
}
posted @   cxy8  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示