码迷,mamicode.com
首页 > 其他好文 > 详细

P3388 【模板】割点(割顶)

时间:2017-11-25 18:24:48      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:pre   输入输出   copy   algorithm   oid   div   cst   输出   std   

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 【模板】割点(割顶)

标签:pre   输入输出   copy   algorithm   oid   div   cst   输出   std   

原文地址:http://www.cnblogs.com/mjtcn/p/7895868.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!