正在载入在线练习界面,本页内容可直接阅读…
AK CSP › CSP-S 2024 第一轮真题 › 第39题
CSP-S 2024 第一轮 第39题:完善程序(第 20 题)第 2 空
题目
(次短路) 已知一个有 $n$ 个点 $m$ 条边的有向图 $G$,并且给定图中的两个点 $s$ 和 $t$,求次短路(长度严格大于最短路的最短路径)。如果不存在,输出一行 $-1$。如果存在,输出两行,第一行表示次短路的长度,第二行表示次短路的一个方案。
#include <cstdio>
#include <queue>
#include <utility>
#include <cstring>
using namespace std;
const int maxn = 2e5+10, maxm = 1e6+10, inf = 522133279;
int n, m, s, t;
int head[maxn], nxt[maxm], to[maxm], w[maxm], tot = 1;
int dis[maxn<<1], *dis2;
int pre[maxn<<1], *pre2;
bool vis[maxn<<1];
void add(int a, int b, int c) {
++tot;
nxt[tot] = head[a];
to[tot] = b;
w[tot] = c;
head[a] = tot;
}
bool upd(int a, int b, int d, priority_queue<pair<int, int>> &q) {
if (d >= dis[b]) return false;
if (b < n) _①_;
q.push(_②_);
dis[b] = d;
pre[b] = a;
return true;
}
void solve() {
priority_queue<pair<int, int>> q;
q.push(make_pair(0, s));
memset(dis, _③_, sizeof(dis));
memset(pre, -1, sizeof(pre));
dis2 = dis+n;
pre2 = pre+n;
dis[s] = 0;
while (!q.empty()) {
int aa = q.top().second; q.pop();
if (vis[aa]) continue;
vis[aa] = true;
int a = aa % n;
for (int e = head[a]; e; e = nxt[e]) {
int b = to[e], c = w[e];
if (aa < n) {
if (!upd(a, b, dis[a]+c, q))
_④;
} else
upd(n+a, n+b, dis2[a]+c, q);
}
}
}
void out(int a) {
if (a != s) {
if (a < n) out(pre[a]);
else out(_⑤_);
}
printf("%d%c", a%n+1, " \n"[a == n+t]);
}
int main() {
scanf("%d%d%d%d", &n, &m, &s, &t);
s--, t--;
for (int i = 0; i < m; ++i) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a-1, b-1, c);
}
solve();
if (dis2[t] == inf) puts("-1");
else {
printf("%d\n", dis2[t]);
out(n+t);
}
}本小题
② 处应填( )
选项
- A. make_pair(-d, b)
- B. make_pair(d, b)
- C. make_pair(b, d)
- D. make_pair(-b, d)
答案
A
题解
应选 A:make_pair(-d, b)。
C++ 的 priority_queue<pair<int, int>> 默认是大根堆,优先弹出第一项最大的元素;而 Dijkstra 算法需要优先处理距离最小的状态。
因此把距离 d 取负后入队:距离越小,-d 越大,就越早出队。例如距离为 3 和 5 时,-3 > -5,距离为 3 的状态先出队。
第二项存状态编号 b,与取队首时的代码对应:
``cpp int aa = q.top().second; ``
所以填:
``cpp q.push(make_pair(-d, b)); ``
真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1
京公网安备11010502062986号