https://www.luogu.com.cn/record/152373498
#include <iostream>
#include <vector>
#include <algorithm>
struct Node // 结点
{
int dfn, low;
};
int node_cnt; // 用来求 dfn
Node vt[20005]; // 点集
std::vector<int> ans; // 割点
std::vector<int> eg[20005]; // 边集
void tarjan(int u, int fa)
{
int son_cnt = 0; // 儿子数, 为根作特判
vt[u].dfn = vt[u].low = ++node_cnt;
for (auto v : eg[u])
if (v != fa)
{
if (vt[v].dfn == 0)
{
tarjan(v, u);
vt[u].low = std::min(vt[u].low, vt[v].low);
if (vt[v].low >= vt[u].dfn)
{
son_cnt++;
if (fa != 0 || son_cnt > 1) // fa != 0 即这个点非根
ans.push_back(u);
}
}
else
vt[u].low = std::min(vt[u].low, vt[v].dfn);
}
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int n, m;
std::cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int x, y;
std::cin >> x >> y;
eg[x].push_back(y);
eg[y].push_back(x);
}
for (int i = 1; i <= n; i++)
if (vt[i].dfn == 0)
tarjan(i, 0);
std::sort(ans.begin(), ans.end());
std::cout << ans.size() << "\n";
for (auto u : ans)
std::cout << u << " ";
std::cout << "\n";
return 0;
}