
图论PLUS
图论PLUS
拓扑排序
Kahn(卡恩)算法
$e[x]$ 存点 $x$ 的邻点,$tp$ 存拓扑序列, $din[x]$ 存点 $x$ 的入度。算法的核心用队列维护一个入度为 $0$ 的节点的集合
- 初始化,队列 $q$ 压入所有入度为 $0$ 的点;
- 每次从 $q$ 中取出一个点 $×$ 放入数组 $tp$;
- 然后将 $x$ 的所有出边删除。若将边 $(x,y)$ 删除后,$y$ 的入度变为 $0$,则将 $y$ 压入 $q$ 中;
- 不断重复 $2,3$ 过程,直到队列 $q$ 为空;
- 若 $tp$ 中的元素个数等于 $n$ ,则有拓扑序;否则,有环。

1 | const int N = 100010; |
找到字典序最小的拓扑排序,将队列换为优先队列(小根堆)。
DFS算法
$e[x]$ 存点 $x$ 的邻点, $tp$ 存拓扑序列, $c[x]$ 存点 $x$ 的颜色。
算法的核心是变色法,一路搜一路给点变色,如果有拓扑序,每个点的颜色都会从 $0→-1→1$ ,经历三次变色。
- 初始状态,所有点染色为 $0$ ;
- 枚举每个点,进入 $x$ 点,把 $x$ 染色为 $-1$ 。然后,枚举 $x$ 的儿子 $y$ ,如果 $y$ 的颜色为 $0$ , 说明没碰过该点,进入 $y$ 继续走;
- 如果枚举完 $x$ 的儿子,没发现环,则 $x$ 染色为 $1$ ,并把 $x$ 压入 $tp$ 数组;
- 如果发现有个熊孩子的颜色为 $-1$ ,说明回到了祖先节点,发现了环,则一路返回
false
,退出程序
1 |
|
- 感谢您的赞赏。
- 支付宝
赞赏名单
因为有你们的支持,我才体会到写文章的价值。
本文是原创文章,采用CC BY-NC-SA 4.0协议,完整转载请注明来自Lumosion's Blog