这道题是一道最短路径树问题。
首先,什么是最短路径树呢?
定义一个图的最短路径树表示一个图上的生成树,且根节点到图上任一点的距离等于原图上两者之间的距离。
而不难发现,题目其实是在求图上最短路径树记数。
首先,建出最短路径树。枚举每条边,判断边两个端点到根的距离之差是否为这条边的边权。如果是,则在最短路径树中加入这条边。
然后,通过乘法原理可知,最短路径树记数其实就是求出每个最短路径树上的点的入度的积。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> p;
const ll N = 1010, mod = 0x7fffffff;
ll n, m;
ll ans = 1;
vector<p> graph[N], graph2[N], graph3[N];
vector<ll> dis(N, 1e9);
bitset<N> vis;
void dijkstra() {
priority_queue<p, vector<p>, greater<>> q;
q.emplace(0, 1);
dis[1] = 0;
while (!q.empty()) {
p cur = q.top();
q.pop();
if (vis[cur.second])
continue;
vis[cur.second] = 1;
for (auto v : graph[cur.second]) {
if (dis[v.second] > dis[cur.second] + v.first) {
dis[v.second] = dis[cur.second] + v.first;
q.emplace(dis[v.second], v.second);
}
}
}
for (ll i = 1; i <= n; i++) {
for (auto v : graph[i]) {
if (dis[i] == dis[v.second] + v.first) {
graph2[v.second].emplace_back(v.first, i);
graph3[i].emplace_back(v.first, v.second);
}
}
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (ll i = 0, u, v, w; i < m; i++) {
cin >> u >> v >> w;
graph[u].emplace_back(w, v);
graph[v].emplace_back(w, u);
}
dijkstra();
vis.reset();
for (int i = 1; i <= n; i++)
if (!graph3[i].empty()) {
ans = (ans * graph3[i].size()) % mod;
}
cout << ans;
return 0;
}
标签:emplace,cur,Loj,题解,ll,路径,second,P10064,dis From: https://blog.csdn.net/iPig4/article/details/140591543