原题

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
inline LL read () {
LL res = ;
int f () ;
char ch = getchar ();
while (!isdigit(ch)) {
if (ch == '-') f = - ;
ch = getchar();
}
while (isdigit(ch)) res = (res << ) + (res << ) + (ch ^ ),ch = getchar();
return res * f ;
}
const int N = +;
int a[N] , nxt [N] , head[N] , dfn[N] , low[N] , cnt , k ;
bool cut[N] , bst[N] ;
inline void Add (int x ,int y) {
a[++k] = y ; nxt[k] = head[x]; head[x] = k ; return ;
}
inline void tarjan (int u,int mr) {
int rc = ;
dfn[u] = low[u] = ++ cnt ;
for ( register int p = head[u] ; p ; p = nxt[p] ) {
int v = a[p] ;
if (! dfn [v]) {
tarjan ( v , mr ) ;
low[u] = min ( low[u] , low[v] );
if (low[v] >= dfn[u] and u != mr) cut[u]=true;
if (u == mr) rc ++ ;
}
low[u] = min ( low[u] , dfn[v] ) ;
}
if (u == mr and rc >= ) cut[mr] = true;
}
signed main() {
int n = read() ;
int m = read() ;
int ans = ;
for ( register int i = ;i <= m ; i ++) {
int x = read() ;
int y = read() ;
Add (x,y) ; Add (y,x) ;
}
for ( register int i = ;i <= n ; i ++)
if ( ! dfn[i] ) tarjan ( i , i ) ;
for ( register int i = ;i <= n ; i ++)
if ( cut[i] ) ans ++ ;
cout << ans << endl ;
for ( register int i = ;i <= n ; i ++)
if ( cut[i] ) cout << i << ' ' ;
return ;
}

首先tarjan求割点的重点就是dfn和low数组的理解。

dfn[i]就是时间戳,即在什么时刻搜索到了点i,

low[i]则是i点能回溯到的dfn最小的祖先,

搜索的时候判断一下当对于点x存在儿子节点y,使得dfn[x]<=low[y]则x一定是割点。

因为只要x的子节点不能回溯到x的上面,就是没有返祖边超过x点,那么割掉x就能造成不连通了

好啦,基本算法介绍完,就要讲几个问题了。

首先,为什么此处

low[a]=min(low[a],dfn[p]);

不能写作

low[a]=min(low[a],low[p]);

在我的理解,由于此处是一张无向图,我们有双向建了边,导致节点可以回溯到它的父节点;

而如果从它的父节点或其父节点的另一棵子树上有向上很多的返祖边,

这时把子节点的low值赋为父节点的low,就可能导致其low==其父节点low<其父节点dfn,

从而使本该是割点的点被忽视了,答案就少了,所以就wa了。

另外本题还有几个注意点:

  1. 给的图不一定是连通图,即求每个联通块的割顶

  2. 输出格式别看错了2333

  3. 链式前向星开边要2倍

随机推荐

  1. STL map的用法介绍!

    map对象的定义 使用前添加map头文件,必须分别指明键和值的类型: map<string,int>word_count; map的构造函数: map<k,v>m;   创建一 ...

  2. idea使用之maven本地索引更新

    idea使用起来的确挺顺手的,但遇到一些问题时,直接百度很难有答案,只能自己慢慢摸索了. 今天在倒腾idea仓库索引的时候,就出事情啦. 先说idea更新本地仓库索引吧,打开settings--> ...

  3. Linux下汇编语言学习笔记5 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  4. 利用mysql分析小规模数据

    1 获取数据 示例:(/home/work/data/1.data) 123457,chenli,70 123458,liuyang,71 2 create table CREATE TABLE sc ...

  5. Servlet开发(3)

    Servlet开发 Servlet过滤器: 主要是对访问主页的用户进行过滤,通过登录系统进入的用户可以看到主页内容,在session中存在currentuser. 可以对此进行判断: package ...

  6. [bzoj2179]FFT快速傅立叶_FFT

    FFT快速傅立叶 bzoj-2179 题目大意:给出两个n位10进制整数x和y,你需要计算x*y. 注释:$1\le n\le 6\times 10^4$. 想法: $FFT$入门题. $FFT$实现 ...

  7. 【转载】Spring Boot【快速入门】2019.05.19

    原文出处:https://www.cnblogs.com/wmyskxz/p/9010832.html   Spring Boot 概述 Build Anything with Spring Boot ...

  8. JSP中HTTP状态码

    以下内容引用自http://wiki.jikexueyuan.com/project/jsp/http-status-codes.html: HTTP请求格式和HTTP响应消息的格式一样,都有以下结构 ...

  9. Servlet实现点击计数器

    以下内容引用自http://wiki.jikexueyuan.com/project/servlet/hits-counter.html: 一.Web页面的点击计数器 很多时候,可能有兴趣知道网站的某 ...

  10. Spring_2_Spring中lazy-init和scope属性

    1)springTest类: public class springTest { @Test public void instanceSpring() { AbstractApplicationCon ...