Files
python/TangDou/AcWing/DCC/Backup/P3388_CutPoint_3.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

55 lines
1.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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算法
vector<int> v; //割点集合
//割点
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]) v.push_back(u);
}
low[u] = min(low[u], dfn[j]);
}
//特例:如果u是根,并且有两个以上的儿子节点,则u为割点
if (u == root && son > 1) v.push_back(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);
//排序+去重
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
//输出割点个数
printf("%d\n", v.size());
//由小到大输出割点
for (int i : v) printf("%d ", i);
return 0;
}