【1003 25 最短路径数量 最大点权】 Emergency
传送门
题意
给定 \(n\) 个点,\(m\) 条边的无向图,起点 \(c_1\) ,终点 \(c_2\) ,\(n\) 个点权,\(m\) 条边的边权, 求从 \(c_1\) 到 \(c_2\) 的最短路径的条数及所有最短路径中的最大点权和
数据范围
\(1\leq n\leq 500\)
题解
- 额外维护从起点到每个点的最短路径个数
pathnum,从起点到每个点的最短路径上的最大点权和cnt dijkstra变形,在用当前路径最短的点进行更新时进行如下判断- 如果更新距离,最短路径个数替换为新的最短路径个数,点权加上当前点
- 如果距离相等,终点累加起点的最短路径条数,点权取最大值
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 510, INF = 0x3f3f3f3f;
int p[N], d[N];
int n, m, c1, c2;
int cnt[N], pathcnt[N];
bool st[N];
struct edge {
int to, cost;
edge(int t, int c) : to(t), cost(c) {}
};
vector<vector<edge>> g(N);
using arr = array<int, 2>;
void dijkstra() {
memset(d, 0x3f, sizeof d);
priority_queue<arr, vector<arr>, greater<arr>> que;
d[c1] = 0;
pathcnt[c1] = 1;
cnt[c1] = p[c1];
que.push({0, c1});
while (!que.empty()) {
auto t = que.top(); que.pop();
for (auto& e : g[t[1]]) {
if (d[e.to] > t[0] + e.cost) {
d[e.to] = t[0] + e.cost;
que.push({d[e.to], e.to});
pathcnt[e.to] = pathcnt[t[1]];
cnt[e.to] = cnt[t[1]] + p[e.to];
} else if (d[e.to] == t[0] + e.cost) {
pathcnt[e.to] += pathcnt[t[1]];
cnt[e.to] = max(cnt[t[1]] + p[e.to], cnt[e.to]);
}
}
}
}
int main() {
cin >> n >> m >> c1 >> c2;
for (int i = 0; i < n; i++) {
cin >> p[i];
}
while (m--) {
int u, v, w; cin >> u >> v >> w;
g[u].push_back(edge(v, w));
g[v].push_back(edge(u, w));
}
dijkstra();
cout << pathcnt[c2] << ' ' << cnt[c2];
}

浙公网安备 33010602011771号