墨染空大佬永远的神, 不过这个看起来更清晰, 能比大佬的代码更加易懂
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
const int NUMBER = 210, EDGE_NUMBER = NUMBER * 2;
int k, edge_number, start_node, end_node;
int dist[NUMBER][NUMBER][20];
struct Edge {
int ver1, ver2, val;
} arr[EDGE_NUMBER];
vector<int> nums;
int len;
int get(int val) {
return lower_bound(nums.begin(), nums.end(), val) - nums.begin();
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> k >> edge_number >> start_node >> end_node;
// 计算k有多少位
len = log2(k);
for (int i = 0; i < edge_number; ++i) {
int ver1, ver2, val;
cin >> val >> ver1 >> ver2;
arr[i] = {ver1, ver2, val};
nums.push_back(ver1);
nums.push_back(ver2);
}
sort(nums.begin(), nums.end());
nums.erase(unique(nums.begin(), nums.end()), nums.end());
start_node = get(start_node), end_node = get(end_node);
memset(dist, 0x3f, sizeof dist);
for (int i = 0; i < edge_number; ++i) {
arr[i].ver1 = get(arr[i].ver1);
arr[i].ver2 = get(arr[i].ver2);
// 初始化点与点之间的初始距离
int ver1 = arr[i].ver1, ver2 = arr[i].ver2;
dist[ver1][ver2][0] = dist[ver2][ver1][0] = min(dist[ver1][ver2][0], arr[i].val);
}
for (int l = 1; l <= len; ++l) {
for (int i = 0; i < nums.size(); ++i) {
for (int j = 0; j < nums.size(); ++j) {
for (int z = 0; z < nums.size(); ++z) {
dist[i][j][l] = min(dist[i][j][l], dist[i][z][l - 1] + dist[z][j][l - 1]);
}
}
}
}
int to_curr[NUMBER], start_to[NUMBER];
memset(start_to, 0x3f, sizeof start_to);
start_to[start_node] = 0;
for (int l = 0; l <= len; ++l) {
if (k >> l & 1) {
memset(to_curr, 0x3f, sizeof to_curr);
for (int i = 0; i < nums.size(); ++i) {
for (int j = 0; j < nums.size(); ++j) {
to_curr[i] = min(to_curr[i], start_to[j] + dist[j][i][l]);
}
}
memcpy(start_to, to_curr, sizeof to_curr);
}
}
cout << to_curr[end_node] << endl;
return 0;
}