建立分层图, 第 i i i层到 i + 1 i + 1 i+1层代表一种优惠决策, 一共 k k k层图
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<double, int> PDI;
const int N = 30010, M = 300010;
const int INF = 0x3f3f3f3f;
int n, m, k;
int head[N], edge_end[M], next_edge[M], edge_index;
double w[M], d[N];
bool vis[N];
void add(int ver1, int ver2, double val) {
edge_end[edge_index] = ver2, next_edge[edge_index] = head[ver1], w[edge_index] = val, head[ver1] = edge_index++;
}
void dijkstra() {
priority_queue<PDI, vector<PDI>, greater<PDI>> queue;
for (int i = 0; i < N; ++i) d[i] = INF;
d[1] = 0;
queue.push({
0, 1});
while (!queue.empty()) {
auto [dis, u] = queue.top();
queue.pop();
if (vis[u]) continue;
vis[u] = true;
for (int i = head[u]; ~i; i = next_edge[i]) {
int ver = edge_end[i];
if (d[u] + w[i] < d[ver]) {
d[ver] = d[u] + w[i];
queue.push({
d[ver], ver});
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
memset(head, -1, sizeof head);
cin >> n >> m >> k;
for (int i = 0; i < m; ++i) {
int u, v, w;
cin >> u >> v >> w;
add(u, v, w);
add(v, u, w);
for (int j = 1; j <= k; ++j) {
// 创建第k层图
add(j * n + u, j * n + v, w);
add(j * n + v, j * n + u, w);
// 每层图之间的边权是半价
double val = w / 2.0;
add((j - 1) * n + u, j * n + v, val);
add((j - 1) * n + v, j * n + u, val);
}
}
// 连接每一层的终点位置
for (int i = 0; i < n; ++i) add(i * n + n, (i + 1) * n + n, 0);
dijkstra();
cout << d[k * n + n] << "\n";
return 0;
}

京公网安备 11010502036488号