这东西学了又忘我是真的没救了.. 明明省选前才学的啊
这种东西都很套路的拿到搜索树中去看
如果一个点子树内没有边能到达这个点及其以上的节点
那么这个点就是割点
当然也要考虑这个点是根的情况 判定条件为子树大于2
#include<bits/stdc++.h>
using namespace std;
int read() {
int _ = 0, ___ = 1; char __ = getchar();
for(; !isdigit(__); __ = getchar()) if(__ == '-') ___ = -1;
for(; isdigit(__); __ = getchar()) _ = (_ << 3) + (_ << 1) + (__ ^ 48);
return _ * ___;
}
const int N = 1e6 + 10;
int to[N << 1], head[N], nxt[N], e;
int n, m, dfn[N], low[N];;
int vis[N], cnt, tot;
void add(int x, int y, bool k = 1) {
to[++ e] = y; nxt[e] = head[x]; head[x] = e;
if(k) add(y, x, 0);
}
void dfs(int x, int root, int fa) {
int sz = 0;
dfn[x] = low[x] = ++ cnt;
for(int i = head[x]; i; i = nxt[i]) {
++ sz;
if(!dfn[to[i]]) {
dfs(to[i], 0, x);
low[x] = min(low[x], low[to[i]]);
if(root && sz >= 2 && !vis[x])
vis[x] = ++ tot;
if(!root && low[to[i]] >= dfn[x] && !vis[x])
vis[x] = ++ tot;
}
else if(to[i] != fa)
low[x] = min(low[x], dfn[to[i]]);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("3388.in", "r", stdin);
freopen("3388.out", "w", stdout);
#endif
n = read(), m = read();
for(int i = 1; i <= m; ++ i)
add(read(), read());
for(int i = 1; i <= n; ++ i)
if(!dfn[i])
dfs(i, 1, 0);
printf("%d\n", tot);
for(int i = 1; i <= n; ++ i)
if(vis[i])
printf("%d ", i);
return 0;
}