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的板子很像?

浙公网安备 33010602011771号