洛谷P2865 [USACO06NOV] Roadblocks G 题解 次短路
题目链接:https://www.luogu.com.cn/problem/P2865
题目大意:求严格次短路。
解题思路:
先 spfa 跑一遍反图(由于是无向图,所以反图和原图其实是一样的图),得到估计函数的确定精确值。
然后 A* 跑一遍,即可。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5005, inf = 1e9;
int n, m, dis[maxn];
bool inq[maxn];
struct Edge {
int v, w;
};
vector<Edge> g[maxn];
void spfa() {
fill(dis+1, dis+n, inf);
dis[n] = 0;
queue<int> que;
que.push(n);
while (!que.empty()) {
int u = que.front();
que.pop();
inq[u] = false;
for (auto &[v, w] : g[u]) {
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
if (!inq[v]) inq[v] = true, que.push(v);
}
}
}
}
struct Node {
int u, f;
bool operator < (const Node &o) const {
return f + dis[u] > o.f + dis[o.u];
}
};
int a_star() {
int ans = inf;
priority_queue<Node> que;
que.push({1, 0});
while (!que.empty()) {
auto [u, f] = que.top();
que.pop();
if (u == n && f > dis[1]) {
return f;
}
for (auto &[v, w] : g[u]) {
if (f + w + dis[v] < ans)
que.push({v, f + w});
}
}
return -1;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0, u, v, w; i < m; i++) {
scanf("%d%d%d", &u, &v, &w);
g[u].push_back({v, w});
g[v].push_back({u, w});
}
spfa();
int ans = a_star();
printf("%d\n", ans);
return 0;
}
浙公网安备 33010602011771号