mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-10-17 21:42:25 +00:00
feat: 添加AT_abc232_g.cpp的Dijkstra算法实现
实现基于优先队列的Dijkstra算法,用于解决特定图结构的最短路径问题。包含图的构建、排序处理以及最短路径计算逻辑。
This commit is contained in:
parent
e70c668e57
commit
218bc31cb3
109
src/10/4/AT_abc232_g.cpp
Normal file
109
src/10/4/AT_abc232_g.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const long long INF = 1e18;
|
||||
struct Edge {
|
||||
int to;
|
||||
long long cost;
|
||||
};
|
||||
|
||||
struct State {
|
||||
long long dist;
|
||||
int v;
|
||||
bool operator>(const State &other) const {
|
||||
return dist > other.dist;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
ios_base::sync_with_stdio(false);
|
||||
cin.tie(NULL);
|
||||
|
||||
int N;
|
||||
long long M;
|
||||
cin >> N >> M;
|
||||
|
||||
vector<long long> A(N), B(N);
|
||||
for (int i = 0; i < N; ++i)
|
||||
cin >> A[i];
|
||||
for (int i = 0; i < N; ++i)
|
||||
cin >> B[i];
|
||||
|
||||
vector<pair<long long, int>> sB(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
sB[i] = {B[i], i};
|
||||
}
|
||||
sort(sB.begin(), sB.end());
|
||||
|
||||
vector<int> p(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
p[i] = sB[i].second;
|
||||
}
|
||||
|
||||
int totnds = 3 * N;
|
||||
vector<vector<Edge>> adj(totnds);
|
||||
|
||||
for (int i = 0; i < N - 1; ++i) {
|
||||
|
||||
adj[N + i + 1].push_back({N + i, sB[i + 1].first - sB[i].first});
|
||||
|
||||
adj[2 * N + i].push_back({2 * N + i + 1, sB[i + 1].first - sB[i].first});
|
||||
}
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
|
||||
long long target_b = M - A[i];
|
||||
auto it = lower_bound(sB.begin(), sB.end(), make_pair(target_b, -1));
|
||||
if (it == sB.end()) {
|
||||
it = sB.begin();
|
||||
}
|
||||
int k = distance(sB.begin(), it);
|
||||
adj[i].push_back({N + k, (A[i] + sB[k].first) % M});
|
||||
|
||||
auto it_v = lower_bound(sB.begin(), sB.end(), make_pair(M - A[i], -1));
|
||||
if (it_v != sB.end()) {
|
||||
int k_v = distance(sB.begin(), it_v);
|
||||
adj[i].push_back({N + k_v, (A[i] + sB[k_v].first) - M});
|
||||
}
|
||||
|
||||
adj[i].push_back({2 * N, A[i] + sB[0].first});
|
||||
}
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
adj[N + i].push_back({p[i], 0});
|
||||
adj[2 * N + i].push_back({p[i], 0});
|
||||
}
|
||||
|
||||
vector<long long> dist(totnds, INF);
|
||||
priority_queue<State, vector<State>, greater<State>> pq;
|
||||
|
||||
dist[0] = 0;
|
||||
pq.push({0, 0});
|
||||
|
||||
while (!pq.empty()) {
|
||||
State cur = pq.top();
|
||||
pq.pop();
|
||||
|
||||
long long d = cur.dist;
|
||||
int u = cur.v;
|
||||
|
||||
if (d > dist[u]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto &edge : adj[u]) {
|
||||
if (dist[u] + edge.cost < dist[edge.to]) {
|
||||
dist[edge.to] = dist[u] + edge.cost;
|
||||
pq.push({dist[edge.to], edge.to});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cout << dist[N - 1] << endl;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user