P3388 模板割点(割顶)

Posted HWIM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3388 模板割点(割顶)相关的知识,希望对你有一定的参考价值。

P3388 【模板】割点(割顶)

题目背景

割点

题目描述

给出一个n个点,m条边的无向图,求图的割点。

输入输出格式

输入格式:

 

第一行输入n,m

下面m行每行输入x,y表示x到y有一条边

 

输出格式:

 

第一行输出割点个数

第二行按照节点编号从小到大输出节点,用空格隔开

 

输入输出样例

输入样例#1: 复制
6 7
1 2
1 3
1 4
2 5
3 5
4 5
5 6
输出样例#1: 复制
1 
5

说明

n,m均为100000

tarjan 图不一定联通!!!

分析

tarjan求割点

code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<cstdlib>
 6 
 7 using namespace std;
 8 
 9 const int N = 100100;
10 struct Edge{
11     int to,nxt;
12 }e[N<<1];
13 int head[N],dfn[N],low[N];
14 bool iscut[N];
15 int tn,tot;
16 
17 inline char nc() {
18     static char buf[100000],*p1 = buf,*p2 = buf;
19     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++;
20 }
21 inline int read() {
22     int x = 0,f = 1;char ch = nc();
23     for (; ch<0||ch>9; ch = nc()) 
24         if (ch==-) f = -1;
25     for (; ch>=0&&ch<=9; ch = nc()) 
26         x = x*10+ch-0;
27     return x * f;
28 }
29 
30 void add_edge(int u,int v) {
31     e[++tot].to = v,e[tot].nxt = head[u],head[u] = tot;
32 }
33 
34 void tarjan(int u,int fa) {
35     low[u] = dfn[u] = ++tn;
36     int cnt_son = 0;
37     for (int i=head[u]; i; i=e[i].nxt) {
38         int v = e[i].to;
39         if (!dfn[v]) {
40             cnt_son++;
41             tarjan(v,u);
42             low[u] = min(low[u],low[v]);
43             if (low[v] >= dfn[u]) 
44                 iscut[u] = true;
45         }
46         else if (dfn[v] < dfn[u] && v != fa) 
47             low[u] = min(low[u],dfn[v]);
48     }
49     if (fa<0 && cnt_son==1) iscut[u] = false;
50 }
51 int main() {
52     int n = read(),m = read();
53     for (int u,v,i=1; i<=m; ++i) {
54         u = read(),v = read();
55         add_edge(u,v),add_edge(v,u);
56     }
57     for (int i=1; i<=n; ++i) 
58         if (!dfn[i]) tarjan(i,-1);
59 
60     int ans = 0;
61     for (int i=1; i<=n; ++i) 
62         if (iscut[i]) ans++;
63     printf("%d\n",ans);
64     for (int i=1; i<=n; ++i) 
65         if (iscut[i]) printf("%d ",i);
66     return 0;
67 }

 

以上是关于P3388 模板割点(割顶)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P3388 模板割点(割顶)

洛谷P3388 模板割点(割顶)

P3388 模板割点(割顶)

P3388 模板割点(割顶)

P3388 模板割点(割顶)

luogu P3388 模板割点(割顶)