LCP 21-追逐游戏
秋游中的小力和小扣设计了一个追逐游戏。他们选了秋日市集景区中的 N 个景点,景点编号为 1~N。此外,他们还选择了 N
条小路,满足任意两个景点之间都可以通过小路互相到达,且不存在两条连接景点相同的小路。整个游戏场景可视作一个无向连通图,记作二维数组 edges
,数组中以[a,b]
形式表示景点 a 与景点 b 之间有一条小路连通。
小力和小扣只能沿景点间的小路移动。小力的目标是在最快时间内追到小扣,小扣的目标是尽可能延后被小力追到的时间。游戏开始前,两人分别站在两个不同的景点startA
和 startB
。每一回合,小力先行动,小扣观察到小力的行动后再行动。小力和小扣在每回合可选择以下行动之一: - 移动至相邻景点
- 留在原地 如果小力追到小扣(即两人于某一时刻出现在同一位置),则游戏结束。若小力可以追到小扣,请返回最少需要多少回合;若小力无法追到小扣,请返回
-1。 注意:小力和小扣一定会采取最优移动策略。 示例 1: >输入:edges = [[1,2],[2,3],[3,4],[4,1],[2,5],[5,6]], startA = 3, startB = 5
> >输出:3
>
解释: >![image.png](https://pic.leetcode-cn.com/1597991318-goeHHr-
image.png){:height=”250px”} > >第一回合,小力移动至 2 号点,小扣观察到小力的行动后移动至 6 号点;
第二回合,小力移动至 5 号点,小扣无法移动,留在原地; >第三回合,小力移动至 6 号点,小力追到小扣。返回 3。 示例 2:
输入:edges = [[1,2],[2,3],[3,4],[4,1]], startA = 1, startB = 3
> >输出:-1
>
解释: >![image.png](https://pic.leetcode-cn.com/1597991157-QfeakF-
image.png){:height=”250px”} > >小力如果不动,则小扣也不动;否则小扣移动到小力的对角线位置。这样小力无法追到小扣。
提示: -edges
的长度等于图中节点个数 -3 <= edges.length <= 10^5
-1 <= edges[i][0], edges[i][1] <= edges.length 且 edges[i][0] != edges[i][1]
-1 <= startA, startB <= edges.length 且 startA != startB
解题思路
本题综合考察了图上的DFS和BFS,有一定的思考价值。
N个节点N条边的连通图,一定有且只有一个环。这是解决本题必须想到的一点。想一想为什么?
接下来,我们就开始分情况讨论了:
- 如果A、B一开始就相邻(有一条A–B的边),那么A第一回合就直接捉到了B。
- 否则,我们找到图中唯一的那个环,将环上的点进行标记。
- 如果环的长度为3,那么这个环并不能让B永远绕着走下去。
- 如果环的长度大于等于4,我们求出B进入环的位置和需要走的距离,再求出A到这个位置的距离。如果A的距离大于B的距离加一,那么B就可以在环上一直绕下去而不被捉到。
- 如果环长为3或A可以在环上拦截B,我们需要找出游戏最多进行的回合数。我们求出A和B到图上所有点的距离,然后枚举各个点。
- 如果A到某个点的距离小于等于B的距离加一,说明A有可能在这个点之前拦截到B,想一想为什么?
- 否则,B可以移动到这个点,游戏至少需要进行的回合数为A到这个点的距离。
- 枚举所有点,就可以找到合法的最大距离。
代码
1 |
|