输入样例
8 14 7 8
100 20 30 10 50 80 100 100
7 1 1
7 2 2
7 3 1
7 4 2
1 2 1
1 5 2
2 5 1
3 4 1
3 5 3
3 6 2
4 6 1
5 6 1
5 8 1
6 8 2
输出样例
8 14 7 8
100 20 30 10 50 80 100 100
7 1 1
7 2 2
7 3 1
7 4 2
1 2 1
1 5 2
2 5 1
3 4 1
3 5 3
3 6 2
4 6 1
5 6 1
5 8 1
6 8 2
样例解释
从 7 到 8 的最短路径有 3 条,其中 2 条都经过城镇 1,于是对应的最高旅游热度值是城镇 1 的热度值 100。解路径为 7->2->5->8,途径城镇 2 和 5,对应的最高旅游热度值是城镇 5 的热度值 50。在最短路径长度相等的情况下,取热度值小的解,故输出的热度值为 50。
思想
dijkstar求最短路,只不过权值是花费。同时,我们在求最小花费路径的同时还需要注意尽量避免走热度相对较大的城市。
code
#include<bits/stdc++.h>
using namespace std;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n,m,s,t;
cin>>n>>m>>s>>t;
vector<int>a(n+1); //提前开辟空间,不然会越界
for(int i=1; i<=n; i++) {
cin>>a[i];
}
vector<vector<pair<int, int>>> g(n + 1);
for (int i = 0; i < m; i ++) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
}
//dijkstar
vector<int> dis(n+1,1e9),path(n+1); //存储花费,存储热度
//priority_queue<array<int, 2>, vector<array<int, 2>>, greater<array<int, 2>>> Q;
priority_queue<array<int, 2>> Q;
dis[s]=0; //从七起点到起点的花费为0
Q.push({0,s}); //把起点加入队列
while (Q.size()) {
auto [d, u] = Q.top();
Q.pop();
if (dis[u] < d) continue;
for (auto [v, w] : g[u]) {
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w; //走较小花费的路
Q.push({ -dis[v], v});
if (v != t) {
path[v] = max(path[u], a[v]); //获取最小花费路径上的最大热度景点的热度
} else {
path[v] = path[u];
}
} else if (dis[v] == dis[u] + w) {
path[v] = min(max(a[v], path[u]), path[v]); //在确定最小花费路径的同时也要避免走热度相对较大的城市
}
}
}
if (dis[t] == 1e9) {
cout << "Impossible\n";
} else {
cout << dis[t] << ' ' << path[t] << '\n';
}
return 0;
}