'commit'
This commit is contained in:
88
TangDou/CSP-J/J-2023/bus_dijsktra_FenCengTu.cpp
Normal file
88
TangDou/CSP-J/J-2023/bus_dijsktra_FenCengTu.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
typedef pair<int, int> PII;
|
||||
const int INF = 0x3f3f3f3f;
|
||||
const int N = 2e6 + 5, M = N << 1; // 1e4的顶点 * 1e2的分层
|
||||
|
||||
// first:起点距离目标点的权重i/ / second:目标点编号
|
||||
int dis[N];
|
||||
// 判断是否以某个顶点作为出发点进行松弛
|
||||
bool st[N];
|
||||
|
||||
// m条边
|
||||
// k个的整数倍
|
||||
int n, m, k;
|
||||
|
||||
// 链式前向星
|
||||
int e[M], h[N], idx, w[M], ne[M];
|
||||
void add(int a, int b, int c = 0) {
|
||||
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
|
||||
}
|
||||
|
||||
// 最短路搜索
|
||||
void dijkstra(int s) {
|
||||
// 优先队列
|
||||
priority_queue<PII> q; // n个顶点
|
||||
memset(dis, INF, sizeof dis);
|
||||
|
||||
// 起点距离自己为0
|
||||
dis[s] = 0;
|
||||
q.push({0, s});
|
||||
|
||||
while (q.size()) {
|
||||
int u = q.top().second;
|
||||
q.pop();
|
||||
// 该点已经被作为起点出发了
|
||||
if (st[u]) continue;
|
||||
// 标记此点已经被作为起点使用过
|
||||
st[u] = 1;
|
||||
|
||||
for (int i = h[u]; ~i; i = ne[i]) {
|
||||
int v = e[i]; // 获取当前顶点的目标点
|
||||
int t = dis[u] + 1; // 到达下一个节点的时间
|
||||
if (t < w[i]) t += ((w[i] - dis[u] + k - 1) / k) * k;
|
||||
// https://www.luogu.com.cn/problem/solution/P9751
|
||||
// while (t < w[i]) t += k;
|
||||
|
||||
// w[i]:最早开放时间
|
||||
// 松弛
|
||||
if (dis[v] > t) {
|
||||
dis[v] = t;
|
||||
// 保证每次筛选出来的都是离起点最近的点
|
||||
q.push({-dis[v], v});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 计算给定的点在新层中的索引
|
||||
int get(int layer, int x) {
|
||||
return layer * n + x;
|
||||
}
|
||||
|
||||
int main() {
|
||||
memset(h, -1, sizeof h); // 初始化链式前向星
|
||||
cin >> n >> m >> k; // 读入m条边的信息
|
||||
while (m--) {
|
||||
// a为起始点//b为终点
|
||||
// c是最早开放时间
|
||||
int a, b, c;
|
||||
cin >> a >> b >> c;
|
||||
|
||||
// 存入分层图
|
||||
// get(i, a) : 当前层点索引
|
||||
// get((i + 1) % k, b):下一层K步后所能到达的点
|
||||
// 当前层和第i+1层建图
|
||||
for (int i = 0; i < k; i++) add(get(i, a), get((i + 1) % k, b), c);
|
||||
}
|
||||
|
||||
// 调用迪克斯特拉
|
||||
dijkstra(1);
|
||||
|
||||
// 没有找到合法路径
|
||||
if (dis[n] == INF)
|
||||
cout << -1 << endl;
|
||||
else
|
||||
cout << dis[n] << endl;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user