正在载入在线练习界面,本页内容可直接阅读…
AK CSP › CSP-S 2026 第一轮真题 › 第 37 题
CSP-S 2026 第一轮 第 37 题:平衡路线:④处应填
题目
给定一张有 $n$ 个顶点、$m$ 条边的无向图,每条边带有符号 '+' 或 '-'。对于一条从顶点 $s$ 到顶点 $t$ 的路线,允许重复经过顶点和边。定义一条路线的权值如下:记 $n^{+}, n^{-}$ 分别为经过的 '+' 边数和经过的 '-' 边数,则该路线的权值为 $∣n^{+}- n^{-}∣$。
请计算从 $s$ 到 $t$ 的路线的最小权值。若不存在从 $s$ 到 $t$ 的路线,则输出 −1。
输入第一行为四个整数 $n, m, s, t$。接下来 $m$ 行,每行给出两个整数 $a, b$ 和一个字符 '+' 或 '-',描述一条连接 $a$ 与 $b$ 的无向边及其符号。
数据满足 $2 \le n \le 2 \times 10^{5}$,$1 \le m \le 4 \times 10^{5}$,$1 \le s, t \le n$ 且 $s ≠=t$,$1 \le a, b \le n$,可能出现重边。
以下程序通过 BFS 求出最小权值。请补全程序。
#include <iostream>
constexpr int N = 200005;
constexpr int M = 400005;
int n, m, s, t;
int h[N], e[M << 1], ne[M << 1], w[M << 1], idx;
int q[N], d[N], c[N];
void add(int a, int b, int z) {
e[idx] = b;
w[idx] = z;
ne[idx] = h[a];
h[a] = idx++;
}
int main() {
std::cin >> n >> m >> s >> t;
for (int i = 1; i <= n; i++)
h[i] = d[i] = c[i] = -1;
for (int i = 0; i < m; i++) {
int a, b;
char op[2];
std::cin >> a >> b >> op;
int z = /* ① */;
add(a, b, z);
add(b, a, z);
}
int hh = 0, tt = 0;
int p = 0, ng = 0, ok = 1;
q[tt++] = s;
d[s] = c[s] = 0;
while (/* ② */) {
int x = q[hh++];
for (int i = h[x]; i != -1; i = ne[i]) {
int y = e[i];
if (w[i] > 0) p = 1;
if (w[i] < 0) ng = 1;
if (d[y] == -1) {
d[y] = /* ③ */;
c[y] = c[x] ^ 1;
q[tt++] = y;
} else if (/* ④ */)
ok = 0;
}
}
if (d[t] == -1) {
std::cout << -1;
return 0;
}
if (!p || !ng) {
std::cout << d[t];
return 0;
}
if (/* ⑤ */) std::cout << 0;
else std::cout << 1;
return 0;
}本小题
④处应填( )。
选项
- A. c[y] == c[x]
- B. w[i] == 1
- C. c[y] != c[x]
- D. d[y] + 1 != d[x]
答案
A
题解
答案是 A.c[y] == c[x]。
这里的 c[x] 表示顶点 x 的颜色,取值为 0 或 1。程序在 BFS 时进行二分图染色:
``cpp c[y] = c[x] ^ 1; ``
^ 1 会把 0 变成 1、把 1 变成 0,所以新发现的顶点 y 会被染成与 x 不同的颜色。
如果 y 已经被访问过,就要检查边的两个端点是否颜色相同:
``cpp else if (c[y] == c[x]) ok = 0; ``
相邻顶点颜色相同,说明染色冲突,即从 s 能到达的连通分量不是二分图,存在奇环。因此,ok 用于记录这个连通分量是否为二分图。
为什么本题要判断二分图?因为路线权值与路线长度的奇偶性相同:
\[ |n^+-n^-|\equiv n^+-n^-\equiv n^++n^-\pmod 2. \]
二分图中,从 s 到 t 的所有路线长度奇偶性固定;存在奇环时,可以通过绕行奇环改变奇偶性。因此,染色结果会影响最终能否得到权值 0。
真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1
京公网安备11010502062986号