一道求割点的板子题。还是采用经典的Tarjan算法。

首先大致和Tarjan求强连通分量相似,都是用\(dfn_x\)表示访问到\(x\)的时间(时间戳),\(low_x\)表示通过\(x\)回边能走到的时间戳最小的点的时间戳。

然后我们考虑一下对于一个点如何判断它是否为割点:

  • 若这个点是我们人为选择的起始节点(根节点),那么当它的子树个数大于等于两个时肯定就是割点(因为这些子树就无法互相到达)
  • 若这个点不是根节点,那么当它的任意一个出点\(y\)的\(low_y>=dfn_x\)时,证明它的儿子无法通过回边回到它前面的点,因此这个点就是割点。

然后注意一下一个经典的细节,在通过回边更新时要写成:

low[now]=min(low[now],dfn[e[i].to]);

而不是

low[now]=min(low[now],low[e[i].to]);

然后引用一下Luogu某大佬taoran的话:

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

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

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

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

然后就当板子题切掉吧。CODE

#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
const int N=100005;
struct edge
{
int to,next;
}e[N<<1];
int head[N],father[N],low[N],dfn[N],cnt,tot,ans,n,m,x,y;
bool cut[N];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void write(int x)
{
if (x>9) write(x/10);
putchar(x%10+'0');
}
inline void add(int x,int y)
{
e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline void Tarjan(int now)
{
dfn[now]=low[now]=++tot; int res=0;
for (register int i=head[now];i!=-1;i=e[i].next)
if (!dfn[e[i].to])
{
father[e[i].to]=now; ++res;
Tarjan(e[i].to); low[now]=min(low[now],low[e[i].to]);
if (father[now]&&low[e[i].to]>=dfn[now]) !cut[now]&&(cut[now]=1,++ans);
} else if (e[i].to!=father[now]) low[now]=min(low[now],dfn[e[i].to]);
if (!father[now]&&res>=2) !cut[now]&&(cut[now]=1,++ans);
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i; read(n); read(m);
memset(e,-1,sizeof(e)); memset(head,-1,sizeof(head));
for (i=1;i<=m;++i)
read(x),read(y),add(x,y),add(y,x);
for (i=1;i<=n;++i)
if (!dfn[i]) Tarjan(i);
for (write(ans),putchar('\n'),i=1;i<=n;++i)
if (cut[i]) write(i),putchar(' ');
return 0;
}

Luogu P3388 【模板】割点(割顶)的更多相关文章

  1. 【Luogu P3388】割点模板

    Luogu P3388 在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多,就称这个点集为割点集合. 如果某个割点集合只含有一个顶点X(也即{X ...

  2. Tarjan求割点(割顶) 割边(桥)

    割点的定义: 感性理解,所谓割点就是在无向连通图中去掉这个点和所有和这个点有关的边之后,原先连通的块就会相互分离变成至少两个分离的连通块的点. 举个例子: 图中的4号点就是割点,因为去掉4号点和有关边 ...

  3. $割点割顶tarjan$

    原题 #include <bits/stdc++.h> using namespace std; typedef long long LL; inline LL read () { LL ...

  4. 洛谷 P3388 割点(割顶) 题解

    题面:     割点性质:     节点 u 如果是割点,当且仅当存在 u 的一个子树,子树中没有连向 u 的祖先的边(返祖边).     换句话说,如果对于一个点u,它的子节点是v,如果low[v] ...

  5. Tarjan求割点 || Luogu P3388 【模板】割点(割顶)

    题面:P3388 [模板]割点(割顶) 题解:无 代码: #include<cstdio> #include<iostream> #include<cstring> ...

  6. P3388 【模板】割点(割顶)

    P3388 [模板]割点(割顶) 题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式 ...

  7. P3388 【模板】割点(割顶) 题解 (Tarjan)

    题目链接 P3388 [模板]割点(割顶) 解题思路 最近学的东西太杂了,多写点博客免得自己糊里糊涂的过去了. 这个题求割点,感觉这篇文章写得挺好. 割点是啥?如果去掉这个点之后连通图变成多个不连通图 ...

  8. 洛谷 P3388 【模板】割点(割顶)(Tarjan)

    题目链接 https://www.luogu.org/problemnew/show/P3388 模板题 解题思路 什么是割点? 怎样求割点? dfn :即时间戳,一张图的dfs序(dfs遍历时出现的 ...

  9. 图论算法-Tarjan模板 【缩点;割顶;双连通分量】

    图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; ...

  10. poj 1144 Network 图的割顶判断模板

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8797   Accepted: 4116 Descripti ...

随机推荐

  1. Selenium Webdriver 动态设置 Proxy

    Step 1: Visiting "about:config" driver.get("about:config"); Step 2 : Run script ...

  2. python ctypes 探究 ---- python 与 c 的交互

    近几天使用 python 与 c/c++ 程序交互,网上有推荐swig但效果都不理想,所以琢磨琢磨了 python 的 ctypes 模块.同时,虽然网上有这方面的内容,但是感觉还是没说清楚.这里记录 ...

  3. 软件工程-CMM与CMMI

    CMM CMMI

  4. [20180718]拷贝数据文件从dg库.txt

    [20180718]拷贝数据文件从dg库.txt 1.测试环境:SCOTT@book> @ ver1PORT_STRING                    VERSION        B ...

  5. linux内存源码分析 - SLAB分配器概述【转】

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 之前说了管理区页框分配器,这里我们简称为页框分配器,在页框分配器中主要是管理物理内存,将物理内存的页框分配给申请 ...

  6. FUSE 文件系统 example部分 源码注释 (libfuse 2.9.9)

    本篇文章主要是针对fuse-2.9.9 Example 部分 给出的源码,结合官方文档,以及网上的资料给出注释,希望能给正在学习的你们一点帮助. Hello.c /* FUSE: Filesystem ...

  7. 第七章 鼠标(CONNECT)

    /* CONNECT.C -- Connect-the-Dots Mouse Demo Program (c) Charles Petzold,1998 */ #include <Windows ...

  8. 一文读懂遗传算法工作原理(附Python实现)

    选自AnalyticsVidhya 参与:晏奇.黄小天 近日,Analyticsvidhya 上发表了一篇题为<Introduction to Genetic Algorithm & t ...

  9. CentOS7下用firewall-cmd控制端口与端口转发

    1.firewalld 守护进程 2.控制端口/服务 3.伪装IP 4.端口转发 实现目标:服务器A和服务器B都是内网互通的,但是只有服务器A是有外网然后现在做端口转发实现服务器B能使用服务器A的外网 ...

  10. PJ可能会考的模拟与枚举-自学教程

    PJ可能会考的模拟与枚举-自学教程 文/Pleiades_Antares 之前学校里看一个小可爱复习的时候偷偷听来着XD 简单记了一下重点吧,希望能对看官您有所帮助XD 以下⬇️是几个复习时讲过的题, ...