题意
有N
个城市,每个城市有点权,M
条带权无向边,从指定的起点城市到达指定的终点城市。要求路径最短,输出这样的最短路径有几条,其中路径上点权之和最大为多少。
思路
最短路,dijkstra。习惯性写堆优化的(自己搞一个结构体,重载一下小于号,代码可能更简洁一点)。因为还要求最短路径数量和路径最大点权和,所以稍微改一下算法:在更新距离不变时,更新答案;更新距离改变时,传递答案。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, m, st, en;
cin >> n >> m >> st >> en;
vector<int> num(n);
for (int &e : num) cin >> e;
vector<vector<pair<int, int>>> adj(n);
for (int i = 0, u, v, val; i < m; ++i) {
cin >> u >> v >> val;
adj[u].emplace_back(v, val);
adj[v].emplace_back(u, val);
}
vector<bool> vis(n, false);
vector<int> dis(n, INT_MAX);
dis[st] = 0;
vector<int> way(n, 0);
way[st] = 1;
vector<int> sum(n, 0);
sum[st] = num[st];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
q.push({0, st});
while (!q.empty()) {
int now, val;
tie(val, now) = q.top();
q.pop();
vis[now] = true;
for (auto e : adj[now]) {
int to, nxt_dis;
tie(to, nxt_dis) = e;
if (vis[to]) continue;
if (dis[to] > dis[now] + nxt_dis) {
dis[to] = dis[now] + nxt_dis;
q.push({dis[to], to});
way[to] = way[now];
sum[to] = sum[now] + num[to];
}
else if (dis[to] == dis[now] + nxt_dis) {
way[to] += way[now];
sum[to] = max(sum[to], sum[now] + num[to]);
}
}
}
cout << way[en] << ' ' << sum[en] << '\n';
return 0;
}
HINT
不定时更新更多题解,详见 git ! ! !
来源:CSDN
作者:xavier_cai
链接:https://blog.csdn.net/abcdefbrhdb/article/details/104652373