https://zhuanlan.zhihu.com/p/101923309 这个链接上看到的
// x 代表当前搜索树的根节点,in_edge 代表其对应的序号(tot)
void tarjan(int x, int in_edge) {
// 在搜索之前,先初始化节点 x 的时间戳与追溯值
dfn[x] = low[x] = ++num;
// 通过 head 变量获取节点 x 的直接连接的第一个相邻节点的序号
// 通过 Next 变量,迭代获取剩下的与节点 x 直接连接的节点的序号
for (int i = head[x]; i; i = Next[i]) {
// 此时,i 代表节点 y 的序号
int y = ver[i];
// 如果当前节点 y 没有被访问过
if (!dfn[y]) {
// 递归搜索以 y 为跟的子树
tarjan(y, i);
// 计算 x 的追溯值
low[x] = min(low[x], low[y]);
// 桥的判定法则
if (low[y] > dfn[x])
bridge[i] = bridge[i ^ 1] = true; // 标记当前节点是否为桥(具体见下文)
}
else if (i != (in_edge ^ 1)) // 当前节点被访问过,且 y 不是 x 的“父节点”(具体见下文)
low[x] = min(low[x], dfn[y]);
}
}