题解:P3388 【模板】割点(割顶)
提示:本篇题解缺乏详细的证明,如有需要,请移步其他题解。
算法介绍
Tarjan 算法,这里用来解决割点问题,时间复杂度为 \(O(n+m)\)。
割点的简要定义是:去掉割点及其所连的边,该图分为两个及以上的连通分量。
接下来讲的是定义与约定。
\(dfn_i\):称为“时间戳”标记,使用 dfs 第一次遍历到的次序。
搜索树:\(n\) 个点,\(n-1\) 条边搜索生成的树。
\(low_i\):称为“追溯值”,表示的是第 \(i\) 个点到以下点时间戳的最小值。
- 以 \(i\) 为根节点的生成树上的点。
- \(i\) 可以通过一条非树边到达的点。
考虑 \(low_i\) 的计算方法:
- 自己肯定可达,即 \(low_i=dfn_i\)。
- 若 \(j\) 为 \(i\) 在生成树上的子节点,则取 \(low_i=\min(low_i,low_j)\)。
- 若 \(j\) 到 \(i\) 为非树边,则根据定义,\(low_i=\min(low_i,dfn_j)\)。
更新 \(low\) 的伪代码如下:
if y is x's son
low_x=min(low_x,low_y)
else
low_x=min(low_x,dfn_y)
如何求割点?
tarjan 算法:
- 若 \(x\) 不为根节点,且 \(dfn_x \le low_y\),则 \(x\) 为割点。
由定义知,即不能回到祖先,那么 \(x\) 点是割点。
我们发现,此方法无法用于判断根节点,于是有下面的方法。
- 若 \(x\) 为根节点,且 \(x\) 有两颗以上的子树,则 \(x\) 为割点。
非常明显,删去后,整张图就分裂了。
正确性证明
显然。
代码实现
这里也应该讲解一下。
- \(dfn\) 和 \(low\) 数组初始全为 \(0\),这点其实也起到标记的作用。
- 在遇到没有访问过的节点时,要继续向下搜索。
- 每个点都有可能是根节点,因为图不连通。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,cnt,p;
vector<int>v[100005];
int dfn[100005],low[100005];
bool ans[100005];
void tarjan(int x,bool root){
int p=0;
dfn[x]=low[x]=++cnt;
for(int i=0;i<v[x].size();i++){
int y=v[x][i];
if(!dfn[y]){
tarjan(y,0);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x]&&!root) ans[x]=1;
if(root) p++;
}
else{
low[x]=min(low[x],dfn[y]);
}
}
if(root&&p>=2) ans[x]=1;
return;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,vv;
cin>>u>>vv;
v[u].push_back(vv);
v[vv].push_back(u);
}
for(int i=1;i<=n;i++){
if(!dfn[i]) tarjan(i,i);
}
int h=0;
for(int i=1;i<=n;i++){
if(ans[i]) h++;
}
cout<<h<<endl;
for(int i=1;i<=n;i++){
if(ans[i]) cout<<i<<" ";
}
return 0;
}
题解:P3388 【模板】割点(割顶)的更多相关文章
- Tarjan求割点(割顶) 割边(桥)
割点的定义: 感性理解,所谓割点就是在无向连通图中去掉这个点和所有和这个点有关的边之后,原先连通的块就会相互分离变成至少两个分离的连通块的点. 举个例子: 图中的4号点就是割点,因为去掉4号点和有关边 ...
- $割点割顶tarjan$
原题 #include <bits/stdc++.h> using namespace std; typedef long long LL; inline LL read () { LL ...
- 洛谷 P3388 割点(割顶) 题解
题面: 割点性质: 节点 u 如果是割点,当且仅当存在 u 的一个子树,子树中没有连向 u 的祖先的边(返祖边). 换句话说,如果对于一个点u,它的子节点是v,如果low[v] ...
- P3388 【模板】割点(割顶) 题解 (Tarjan)
题目链接 P3388 [模板]割点(割顶) 解题思路 最近学的东西太杂了,多写点博客免得自己糊里糊涂的过去了. 这个题求割点,感觉这篇文章写得挺好. 割点是啥?如果去掉这个点之后连通图变成多个不连通图 ...
- Tarjan求割点 || Luogu P3388 【模板】割点(割顶)
题面:P3388 [模板]割点(割顶) 题解:无 代码: #include<cstdio> #include<iostream> #include<cstring> ...
- P3388 【模板】割点(割顶)
P3388 [模板]割点(割顶) 题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式 ...
- 洛谷 P3388 【模板】割点(割顶)(Tarjan)
题目链接 https://www.luogu.org/problemnew/show/P3388 模板题 解题思路 什么是割点? 怎样求割点? dfn :即时间戳,一张图的dfs序(dfs遍历时出现的 ...
- 图论算法-Tarjan模板 【缩点;割顶;双连通分量】
图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; ...
- poj 1144 Network 图的割顶判断模板
Network Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8797 Accepted: 4116 Descripti ...
- POJ 1144 Network(无向图的割顶和桥模板题)
http://poj.org/problem?id=1144 题意: 给出图,求割点数. 思路: 关于无向图的割顶和桥,这篇博客写的挺不错,有不懂的可以去看一下http://blog.csdn.net ...
随机推荐
- 【ABAQUS 二次开发笔记】Python 报错收集和解决方法
1. 运行报错,找不到本地文件及模块.自定义模块 1.1 Example: $/home/tops/bin/python xxx.py Traceback (most recent call last ...
- Selenium IDE工具:火狐浏览器实例讲解IDE命令
在本文中,通过Firefox浏览器上的示例学习Selenium IDE: 我们将使用的网址是"https://accounts.google.com"作为测试程序,通过本文你会 了 ...
- PanWeiDB2.0异构数据库访问测试
PanWeiDB2.0异构数据库访问测试 异构数据库访问兼容性测试一览表 No 访问路径 多维度结果 备注 1 PanWeiDB(集中式)-访问-PanWeiDB(集中式) √ 支持复杂SQL 2 P ...
- [Qt基础内容-04] QCheckBox
QCheckBox 文章目录 QCheckBox 简介 信号 样式设计 本文主要根据QT官方帮助文档以及日常使用,简单的介绍一下QCheckBox的功能以及使用 简介 QCheckBox是一个按钮,其 ...
- Huawei Cloud EulerOS上安装sshpass
下载源码 git clone https://github.com/kevinburke/sshpass.git 由于网络问题,这里我用了一个代理下载 git clone https://ghprox ...
- php 配置Gmail 发送邮件 PHPMailer
hotmail 获取邮箱授权码 准备 首先你应该登陆https://mail.google.com地址,注册一个Gmail邮箱,然后设置开启IMAP访问 打开设置,开启IMAP访问 获取应用专用密码 ...
- celery 启动显示警告信息“...whether broker connection retries are made during startup in Celery 6.0 and above...”
博客地址:https://www.cnblogs.com/zylyehuo/ # celery作为一个单独项目运行,在settings文件中设置 broker_connection_retry_on_ ...
- SpringBoot+使用过滤器链执行风控决策
风控流程 下单前进行风控校验 // 1.begin---风控处理---前置处理{黑白名单校验} RiskControlRuleEnum controlRuleEnum = riskControlHan ...
- Linux+Typora+Picgo图床配置
Linux+Typora+Picgo图床配置 首先不建议安装在UbuntuStore里的版本,会有一些限制. 首先安装node.js 去官网下载编译好的源码,配置软连接,使全局都可以使用node命令. ...
- sql 使用with 递归
---前提:有上下级关系的关系表 ---示例:组织架构表 DECLARE @orgId NVARCHAR(20)='0001'; --向下递归,查询@orgId 下的所有结点...包括儿子-孙子节 ...