求割点 割边
Tarjan
void Tarjan(int u, int fa) { int i, v, child = 0; dfn[u] = low[u] = ++dfn_num; for (i=head[u]; i; i=edge[i].lst) { v = edge[i].to; if (v == fa) continue; if (!dfn[v]) { // 树边, 父子边 Tarjan(v, u); child++; low[u] = min(low[u], low[v]); // case 1 u是根节点,同时只是有2颗子树---> 无向图 所以可能有多个根节点. if (fa==u && child>=2) ans.insert(u) ; // 根节点是否有多颗子树.. 注意 这个是写在if (!vis[u])里面的. // case 2 u是叶子节点, 割点条件是low[v]>=dfn[u] if (fa!=u && low[v] >= dfn[u]) ans.insert(u); // 说明v无法连接到u的祖先. // 桥 的条件是: low[v] > dfn[u] if (low[v] > dfn[u]) ans_pt.insert(Point(u, v)); // 说明v无法连接到u或者u的祖先. } else { low[u] = min(low[u], dfn[v]); // u v 为回边 } } }