题目链接:https://www.luogu.com.cn/problem/P3388
【模板】割点(割顶)
题目背景
割点
题目描述
给出一个 $n$ 个点,$m$ 条边的无向图,求图的割点。
输入格式
第一行输入两个正整数 $n,m$。
下面 $m$ 行每行输入两个正整数 $x,y$ 表示 $x$ 到 $y$ 有一条边。
输出格式
第一行输出割点个数。
第二行按照节点编号从小到大输出节点,用空格隔开。
样例 #1
样例输入 #1
6 7
1 2
1 3
1 4
2 5
3 5
4 5
5 6
样例输出 #1
1
5
提示
对于全部数据,$1\leq n \le 2\times 10^4$,$1\leq m \le 1 \times 10^5$。
点的编号均大于 $0$ 小于等于 $n$。
tarjan图不一定联通。
关于割点不会的同学可参考OI-Wiki:https://oi-wiki.org/graph/cut/
模板代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<map> 5 #include<queue> 6 #include<set> 7 #include<algorithm> 8 #include<stack> 9 #include<cmath> 10 #include<cstring> 11 #include<string> 12 using namespace std; 13 #define gc getchar() 14 #define rd(x) read(x) 15 #define el '\n' 16 #define rep(i, a, n) for(int i = (a); i <= n; ++i) 17 #define per(i, a, n) for(int i = (a); i >= n; --i) 18 using ll = long long; 19 using db = double; 20 using ldb = long double; 21 const int mod = 1e9 + 7; 22 const int inf = 0x3f3f3f3f; 23 const int N = 2e4 + 10; 24 25 template <typename _T> 26 inline void read(_T & f) { 27 f = 0; _T fu = 1; char c = gc; 28 while (c < '0' || c > '9') { if (c == '-') { fu = -1; } c = gc; } 29 while (c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = gc; } 30 f *= fu; 31 } 32 33 template <typename T> 34 void print(T x) { 35 if (x < 0) putchar('-'), x = -x; 36 if (x < 10) putchar(x + 48); 37 else print(x / 10), putchar(x % 10 + 48); 38 } 39 40 template <typename T> 41 void print(T x, char t) { 42 print(x); putchar(t); 43 } 44 45 struct node { 46 int to, next; 47 }e[N << 4]; 48 49 int head[N << 4], tot; 50 51 void add(int u,int v) { 52 e[tot].to = v; 53 e[tot].next = head[u]; 54 head[u] = tot++; 55 } 56 57 int vis[N], dfn[N], low[N], cnt, flag[N]; 58 int res = 0; 59 60 void tarjan(int u,int fa) { 61 vis[u] = 1; 62 dfn[u] = low[u] = ++cnt; 63 int child = 0; 64 for(int i = head[u]; i + 1; i = e[i].next) { 65 int v = e[i].to; 66 if(!vis[v]) { 67 child++; 68 tarjan(v, u); 69 low[u] = min(low[u], low[v]); 70 if(fa != u && low[v] >= dfn[u] && !flag[u]) { 71 flag[u] = 1; 72 res++; 73 } 74 }else if(v != fa) { 75 low[u] = min(low[u], dfn[v]); 76 } 77 } 78 if(u == fa && child >= 2 && !flag[u]) { 79 flag[u] = 1; 80 res++; 81 } 82 83 return; 84 } 85 86 int main() { 87 88 int n, m; 89 cin >> n >> m; 90 memset(head, -1, sizeof(head)); 91 for(int i = 1; i <= m; i++) { 92 int u, v; 93 cin >> u >> v; 94 add(u, v),add(v, u); 95 } 96 for(int i = 1;i <= n; i++) { 97 if(!vis[i]) { 98 cnt = 0; 99 tarjan(i, i); 100 } 101 } 102 cout << res << el; 103 for(int i = 1;i <= n; i++) { 104 if(flag[i]) { 105 cout << i << ' '; 106 } 107 } 108 109 return 0; 110 }标签:10,割顶,洛谷,int,割点,print,using,include From: https://www.cnblogs.com/wabi/p/16750142.html