P1144 最短路计数

题面

题目解析

一开始,想的是bfs对不对,无向无权图嘛!
可能有这种写法,但是分享一种很好写的Dij写法
你可能认为这根本没必要,实则不然,我们在更新Dij的时候,可以这样:

#include <bits/stdc++.h>

using namespace std;

constexpr int N = 1e6 + 2;
constexpr int MOD = 100003;
vector<pair<int, int>> a[N];
int d[N];
bool f[N];
int dp[N];

inline void dij(int s) {
    dp[1] = 1; // 起点一个最短路
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    memset(d, 127, sizeof d);
    d[s] = 0;
    q.push({0, s});
    while (!q.empty()) {
        auto p = q.top();
        q.pop();
        int now = p.second;
        if (p.first > d[now]) continue;
        if (f[now]) continue;
        f[now] = true;
        for (auto i : a[now]) {
            int x = i.first, y = i.second;
            if (d[x] > d[now] + y) {
                d[x] = d[now] + y;
                q.push({d[x], x});
				dp[x] = dp[now] % MOD; // 如果新的权值更大,是不是就要继承now的值,前面就没用了
            } else if (d[x] == d[now] + y) {
				q.push({d[x], x});
				dp[x] = (dp[x] + dp[now]) % MOD; // 如果新的权值一样,是不是加上这个值,应为两条都是最短路
			}
        }
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    
    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        a[u].push_back({v, 1});
        a[v].push_back({u, 1}); // 无向边
    }

    dij(1);
    // for (int i = 1; i <= n; i++) {
    //     cout << d[i] << " ";
    // }

    for (int i = 1; i <= n; i++) {
        cout << dp[i] << '\n';
    }

    
    return 0;
}

是不是和Dij的板子很像?

posted @ 2026-04-09 19:46  PCMSFV  阅读(5)  评论(0)    收藏  举报