You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
const int M = 10010;
int n, m;
int dist[N][2];
int cnt[N][2];
bool st[N][2];
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
// 本题需要一个三个属性的对象最短距离d,最短、次短k,id:节点号
struct Node {
int d, k, id;
// 小顶堆需要重载大于号,大顶堆需要重载小于号
bool const operator>(Node b) const {
return d > b.d;
}
};
void dijkstra(int S) {
memset(dist, 0x3f, sizeof dist);
memset(st, false, sizeof st);
memset(cnt, 0, sizeof cnt);
priority_queue<Node, vector<Node>, greater<>> pq; // 小顶堆
dist[S][0] = 0;
cnt[S][0] = 1;
pq.push({0, 0, S});
while (pq.size()) {
auto t = pq.top();
pq.pop();
int u = t.id;
int k = t.k;
if (st[u][k]) continue;
st[u][k] = true;
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
int d = dist[u][k] + w[i];
if (dist[v][0] > d) { // 比最短路还要短
dist[v][1] = dist[v][0]; // 最短降为次短
cnt[v][1] = cnt[v][0]; // 次短路数量被更新
pq.push({dist[v][1], 1, v}); // 次短被更新,次短入队列
dist[v][0] = d; // 替换最短路
cnt[v][0] = cnt[u][k]; // 替换最短路数量
pq.push({dist[v][0], 0, v}); // 最短路入队列
} else if (dist[v][0] == d) // 增加最短路的数量
cnt[v][0] += cnt[u][k];
else if (dist[v][1] > d) { // 替换次短路
dist[v][1] = d;
cnt[v][1] = cnt[u][k];
pq.push({dist[v][1], 1, v}); // 次短路入队列
} else if (dist[v][1] == d)
cnt[v][1] += cnt[u][k];
}
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d %d", &n, &m);
memset(h, -1, sizeof h);
idx = 0;
while (m--) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
add(a, b, c);
}
int S, F;
scanf("%d %d", &S, &F);
dijkstra(S);
int ans = cnt[F][0]; // 最短路
// 在正常处理完最短路和次短路后,在最后的逻辑中,增加本题的中特殊要求部分
if (dist[F][0] == dist[F][1] - 1) ans += cnt[F][1];
printf("%d\n", ans);
}
return 0;
}