0%

Codeforces Round 1085 (Div. 1 + Div. 2)——CF-2207-D. Boxed Like a Fish(阻塞者阻止移动者前往叶子节点)(暴力程序 bfs 的书写,最重要的还是和做题的一样的,用什么代表一个状态)(有环的话,不能够使用记忆化 dfs,毕竟记忆化 dfs 就是 dp,只能够在 DAG 上使用)(像这种博弈题目,一定要想到的就是两者的最优策略是什么?一定要想两者的最优策略)

题目大意

题目描述
给定一棵包含 nn 个节点的无根树。

Cyndaquil 起初位于一个非叶子节点 vv。在每一个回合中,他可以选择停留在当前节点,或者移动到相邻的一个节点。他的目标是到达树的任意一个叶子节点(度数为 11 的节点)。

Snorlax 试图阻止他到达叶子节点。Snorlax 可以选择在一条边上睡觉,此时 Cyndaquil 将无法通过这条边。同一时刻最多只有一条边会被阻塞(即只有最新选择的边会被阻塞)。

Snorlax 移动有冷却时间。初始时冷却时间为 00。当冷却时间 0\le 0 时,Snorlax 可以选择一条新的边进行阻塞(他也可以选择暂不行动)。一旦他移动并选择了一条新边,冷却时间就会重置为 kk

在 Cyndaquil 的每个回合之后(即使他选择停留),Snorlax 的冷却时间都会减少 11

两人轮流行动,Snorlax 先手,且初始时没有任何边被阻塞。假设双方都采取最优策略,判断 Cyndaquil 是否一定能在有限的回合内到达某个叶子节点。

输入格式
第一行包含一个整数 tt (1t1041 \le t \le 10^4),表示测试用例的数量。

每个测试用例的第一行包含三个整数 nnkkvv (3n51053 \le n \le 5 \cdot 10^51k,vn1 \le k, v \le n),分别表示树的节点数、Snorlax 的冷却时间以及 Cyndaquil 的初始起点。

接下来 n1n-1 行,每行包含两个整数 aabb (1a,bn1 \le a, b \le naba \neq b),表示树上连接节点 aabb 的一条边。

保证给定的图是一棵树,且起点 vv 不是叶子节点。所有测试用例的 nn 之和不超过 51055 \cdot 10^5

输出格式
对于每个测试用例,输出一行 “YES” 或 “NO”(大小写不敏感),表示 Cyndaquil 是否一定能在有限回合内到达叶子节点。

样例输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
6
6 2 1
1 2
2 3
2 4
1 5
5 6
7 1 4
1 2
2 3
3 4
4 5
5 6
6 7
3 1 3
1 3
2 3
4 1 4
1 3
3 4
4 2
9 3 5
4 5
5 6
4 7
9 8
8 7
1 2
2 3
3 4
9 4 5
4 5
5 6
4 7
9 8
8 7
1 2
2 3
3 4

样例输出

1
2
3
4
5
6
YES
NO
YES
NO
NO
YES

样例解释
在第一个测试用例中:Cyndaquil 从节点 11 出发。如果 Snorlax 选择阻塞节点 11 到节点 22 的边,那么 Cyndaquil 可以在两个回合后走到叶子节点 66。否则,Cyndaquil 可以直接移动到节点 22,此时 Snorlax 无法同时阻止他前往叶子节点 3344,Cyndaquil 必然能到达其中一个。

在第二个测试用例中:由于冷却时间 k=1k=1 极短,Snorlax 可以频繁移动,可以证明 Snorlax 能够无限期地阻止 Cyndaquil 到达树两端的叶子节点 1177

image

不难发现样例 2,移动者会被困在 3,4 之间,因为阻塞者冷却时间太快了,只有 1。

image

样例 5 到达不了叶子节点

暴力程序书写指导

暴力程序 bfs 的书写**,最重要的还是和做题的一样的,用什么代表一个状态。**

为什么要书写暴力 bfs 程序?因为以我的这个经验,这种图论题目,你想一遍写对,基本不可能,以类似题目 F 为例:

2025-沈阳站-区域赛-F. The Bond Beyond Time(友谊天长地久)(如何使用 bfs 找一个无弦环)(这种题目,我感觉啊,想要做出来的话,要么就是你的思路得比较好,要么就是还是得写个对拍)

这道题目有一个地方还是很难想到的,需要写一个对拍。

在写一个暴力程序之前(当然,特别暴力的除外啊,特别暴力的就不用想了,但是不是所有的题目都可以非常轻松的找到一个特别暴力的写法,特别是这种博弈题目),一定要想清楚这个状态转移图像

我们不难得到这样的图像:

image

然后,我们来想如何具体实现,这种样子,我们非常容易想到这个记忆化 dfs。但是有环的话,不能够使用记忆化 dfs,毕竟记忆化 dfs 就是 dp,只能够在 DAG 上使用

于是我们想到记忆化 bfs。但是一次正向的记忆化 bfs 很难实现类似的这种可以计算前驱后驱的这个复杂运算。

但是一次不行,就跑两次呗。我们可以跑一次正向 bfs,记住这个出去的红色节点数量(即红色出度)和出去的这个蓝色节点数量(即蓝色出度)。(你也可以理解这次 bfs 就是在把这张反图建出来,毕竟不把图建出来,很难进行这个反向 bfs)然后再跑一次这个反向 bfs,从所有合法点一路往上推,通过减去红色计数器和蓝色计数器,实现类似于或的效果,把红色计数器和蓝色计数器并起来,实现红蓝 and 的效果。

当然我们也不知道对不对,试一试吧。

试过了,上面👆这种做法很难写对,也不是错吧,很难写对。我们不妨啊,一轮,拆成两个操作来看,这样可以避免红蓝之间转移的尴尬问题。

image

一定要把这个状态转移图设计为红蓝互不相交的情况,至少要把逃跑者选择和阻塞者选择分开

好的暴力果然是非常优美啊,一次写对。

采用了朴素的,不动点式的更新方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
bool changed=true;
while (changed) {
changed=false;
for (const auto &[u,vec]:complex_g) {
if (win[u]) continue;
if (u.turn) {
bool all_win=true;
for (auto son:vec) {
if (!win[son]) {
all_win=false;
break;
}
}
win[u]=all_win;
if (all_win) {
changed=true;
}
}else {
for (auto son:vec) {
if (win[son]) {
win[u]=true;
changed=true;
break;
}
}
}
}
}

思路讲解

S 只要符合这个要求,就是 Yes,否则就是 No。

image

其实像上面👆这么想,有一个非常阴的地方,就是,阻塞者是动态的,且可以不操作的,阻塞者可能不急于操作,而是看你怎么操作以后,他再出手,逼你从优势位置移动出来。这么讲很抽象是吧?我们直接拿对拍出来的样例来说。

1
2
3
4
5
6
7
8
9
1
7 2 1
1 2
1 3
2 4
1 5
5 6
3 7

这个样例应该输出 no,原因和上面说的一样。阻塞者可能不急于操作,而是看你怎么操作以后,他再出手,逼你从优势位置移动出来

image

所以说要怎么解决这个问题呢?还是挺难的。

像这种博弈题目,一定要想到的就是两者的最优策略是什么?一定要想两者的最优策略是什么。

Snorlax 试图阻止 Cyndaquil 到达叶子节点,他的最优策略是在 Cyndaquil 即将到达叶子节点(或必胜节点)前的最后一步进行封锁。我们其实已经通过对拍呀,通过什么方式找到了这个比较特殊的这个例子。但是我们没有总结出来,就是阻塞者他的这个策略是什么,就这种博弈题目一定要去想他们的最优策略是什么

因此,其实我们就是看这个拉扯距离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
auto dfs=[&](auto && go,ll u,ll fa) -> void {
if (SZ(g[u])==1) {
return;
}
vector<ll> rec;
ll lans=INF;
for (auto to:g[u]) {
if (to==fa) {
continue;
}
go(go,to,u);
rec.push_back(dp[to]);
lans=min(dp[to]+1,lans);
}
sort(all(rec));
if (SZ(rec)>=2) {
// rec[0]+rec[1]+2 是拉扯距离总长度
// -1 是因为这个在最后一刻他卡你一下,你需要跑的距离就是总拉扯距离 -1
if (rec[0]+rec[1]+2-1<=K) {
lans=0;
}
}
dp[u]=lans;
};
dfs(dfs,S,-1);
if (dp[S]==0) {
cout<<"YES\n";
return;
}
cout<<"NO\n";

AC代码

AC
https://codeforces.com/contest/2207/submission/366188285

心路历程(WA,TLE,MLE……)