题目链接:
题目分析:
割点模板,对于当前搜索的节点是不是搜索树里的根节点分类讨论
- 如果是根节点,显然如果它的子树数量(>=2),把它(cut)掉两棵子树就不连通了
- 如果不是根节点,如果有搜到的节点(low[v] >= dfn[u]),说明有节点不通过(u)没办法上翻到环外,那么把它(cut)掉也是可行的
没了
代码:
#include <bits/stdc++.h>
#define N (300000 + 10)
using namespace std;
inline int read() {
int cnt = 0, f = 1; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + c - '0'; c = getchar();}
return cnt * f;
}
int nxt[N], first[N], to[N], tot, sign, low[N], dfn[N], cnt;
int ans[N], son[N], flag;
void Add(int x, int y) {nxt[++tot] = first[x], first[x] = tot, to[tot] = y;}
void tarjan (int u, int fa) {
dfn[u] = low[u] = ++sign;
for (register int i = first[u]; i; i = nxt[i]) {
if (!dfn[to[i]]) {
tarjan(to[i], fa), low[u] = min(low[u], low[to[i]]);
if (u == fa) ++son[u];
if (low[to[i]] >= dfn[u] && u != fa) ans[++cnt] = u;
}
else if (dfn[to[i]] < low[u]) low[u] = min(low[u], dfn[to[i]]);
}
if (u == fa && son[u] >= 2) ans[++cnt] = u;
}
int n, m, x, y;
int main() {
// freopen("1.in", "r", stdin);
n = read(), m = read();
for (register int i = 1; i <= m; i++) {
x = read(), y = read();
Add(x, y), Add(y, x);
}
for (register int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i, i);
sort(ans + 1, ans + cnt + 1);
int q = unique (ans + 1, ans + cnt + 1) - ans - 1;
printf("%d
", q);
for (register int i = 1; i <= q; i++) printf("%d ", ans[i]);
return 0;
}