AcWing 1134. 最短路计数
题目传送门
一、BFS方法
#include
using namespace std;
const int N = 4e5 + 10;
const int mod = 100003;
int h[N], ne[N], e[N], idx;
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int cnt[N]; //从顶点1开始,到其他每个点的最短路有几条
int dist[N]; //最短距离
int n, m;
void bfs() {
memset(dist, 0x3f, sizeof dist);
queue q;
q.push(1);
cnt[1] = 1; //从顶点1开始,向顶点1的最短路有1条
dist[1] = 0; //距离为0
while (q.size()) {
int t = q.front();
q.pop();
for (int i = h[t]; ~i; i = ne[i]) {
int j = e[i];
if (dist[j] > dist[t] + 1) {
dist[j] = dist[t] + 1;
q.push(j);
cnt[j] = cnt[t];
} else if (dist[j] == dist[t] + 1)
cnt[j] = (cnt[j] + cnt[t]) % mod;
}
}
}
int main() {
memset(h, -1, sizeof h);
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int a, b, c;
cin >> a >> b;
add(a, b), add(b, a);
}
bfs();
for (int i = 1; i <= n; i++)
printf("%d\n", cnt[i]);
}
二、Dijkstra方法
#include
using namespace std;
typedef pair PII;
const int N = 100010, M = 400010;
const int MOD = 100003;
int n, m;
int cnt[N];
int d[N];
bool st[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++;
}
void dijkstra(int start) {
memset(d, 0x3f, sizeof d);
d[start] = 0;
//出发点到自己的最短路径只能有1条
cnt[start] = 1;
//小顶堆q
priority_queue, greater> q;
q.push({0, start});
while (q.size()) {
auto t = q.top();
q.pop();
int u = t.second, dist = t.first;
if (st[u]) continue;
st[u] = true;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (d[j] > dist + 1) {
d[j] = dist + 1;
cnt[j] = cnt[u];
q.push({d[j], j});
}
//只有当当前值可以被更新时才加入到队列当中,(bfs同理)
else if (d[j] == dist + 1)
cnt[j] = (cnt[j] + cnt[u]) % 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(1);
for (int i = 1; i <= n; i++) cout << cnt[i] << endl;
return 0;
}