You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
1.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 2e4 + 10, M = 2e5 + 10;
//链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int n, m; // n个顶点,m条边
int dfn[N], low[N], timestamp, root; // tarjan算法
unordered_set<int> s; // 割点集合,自带排序+去重
//割点
void tarjan(int u) {
low[u] = dfn[u] = ++timestamp;
int son = 0;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!dfn[j]) {
son++;
tarjan(j);
low[u] = min(low[u], low[j]);
//根据割点分析low[j]>= dfn[u]的时候u是割点
//由于u可能有多个子节点都会产生回边u可能进入多次后面需要去重
if (u != root && low[j] >= dfn[u]) s.insert(u);
}
low[u] = min(low[u], dfn[j]);
}
//特例如果u是根并且有两个以上的儿子节点则u为割点
if (u == root && son > 1) s.insert(u);
}
int main() {
scanf("%d %d", &n, &m);
memset(h, -1, sizeof h);
for (int i = 1; i <= m; i++) {
int a, b;
scanf("%d %d", &a, &b);
add(a, b), add(b, a);
}
for (root = 1; root <= n; root++)
if (!dfn[root]) tarjan(root);
//输出割点个数
printf("%d\n", s.size());
//由小到大输出割点
for (auto it = s.begin(); it != s.end(); it++)
printf("%d ", *it); //注意这里是 *it,是迭代器的值的意思
return 0;
}