feat: 添加AT_abc232_g.cpp的Dijkstra算法实现

实现基于优先队列的Dijkstra算法,用于解决特定图结构的最短路径问题。包含图的构建、排序处理以及最短路径计算逻辑。
This commit is contained in:
Zengtudor 2025-10-05 11:19:37 +08:00
parent e70c668e57
commit 218bc31cb3

109
src/10/4/AT_abc232_g.cpp Normal file
View 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;
}