描述
给一个任意图, 一个先手的起始点. 两个人按顺序走子, 第一个不能再前进的人输. 具体描述去官网看. 因为可能有环, (预料到自己要输的那个人)可以无限次在环上移动, 这个时候判平局Draw
.
判断先手的结果(Win
, Draw
, Lose
).
思路
- 先手胜利的条件是, 从起点开始可以走奇数步到达一个出度为
0
的点. (这时轮到后手走, 但是她已经不能再动了). - 如果存在奇数长度的环, 走一遍环, 步数的奇偶性也会改变
- 因为上一点, 访问过的节点还可以再访问一遍, 当且仅当到达这个节点的步数奇偶性不同. 所以要开一个
2*nodes
的dp
或者seen
二维数组.dp[i][0]
表示是否偶数步走到i
点,dp[i][1]
表示是否在奇数步走到i
点. - 开一个
pre
数组来记录上一个值(节点转移) - 在dfs的过程中顺便判断是否有环. 有环的话, 先手肯定不会输.
- dfs递归版本的代码正确但是Python果断TLE, 于是改成stack, WA了几发之后ac. 为什么会WA呢? 因为没注意到后续遍历…判断环时用到了mask数组表示这个点是否正在被访问, 类似
mask[i]=1;dfs(i);mask[i]=0
的操作, 只有在i
这个节点的所有子节点都被访问完之后,mask[i]
才能恢复成0
. 属于后序遍历. 用stack的话, 需要记录第一次访问, 第二次访问. 只有第二次访问时才可以彻底出栈, 设置mask[i]=0
.
代码
AC版本, stack:
1 | # 936B |
TLE, recursive dfs:
1 | # 936B |