tarjan算法应用 割点 桥 双连通分量
tarjan算法的应用。
还需多练习…….遇上题目还是容易傻住
对于tarjan算法中使用到的Dfn和Low数组.
low[u]:=min(low[u],dfn[v])——(u,v)为后向边,v不是u的子树;
low[u]:=min(low[u],low[v])——(u,v)为树枝边,v为u的子树;
1.求割点:
割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点。
原理:若low[v]>=dfn[u],则u为割点。因low[v]>=dfn[u],则说明v通过子孙无法到达u的祖先。那么对于原图,去掉u后,必然会分成两个子图。
所以处理节点u时,先递归v的子节点,然后回溯至u时,如果满足low[v]>=dfn[u],则u为割点。
int tarjan(int x)
{
v[x]=1; //点的状态标记,1为已访问,2为割点
Dfn[x]=Low[x]=time++;
for(int i=head[x];i;i=next[i])
{
if(!v[ver[i]])
{
tarjan(ver[i]);
Low[x]=min(Low[x],Low[ver[i]]);
if(Dfn[x]<=low[ver[i]])
v[x]++;
}
else
Low[x]=min(low[x],Dfn[ver[i]]);
if((x==1&&v[x]>2)||(x>1&&v[x]>1)) //对第一个特判
v[x]=2;
else
v[x]=1;
}
}
2.求桥
桥(割边):删掉它之后,图必然会分裂为两个或两个以上的子图。
原理:若low[v]>dfn[u],则(u,v)为桥。由割点同理可得。但是由于可能存在重边,需要把一条无向边拆成的两条标号相同的有向边,记录每个点的父亲到它的边的标号,如果边(u,v)是v的父亲边,就不能用dfn[u]更新low[v]。这样如果遍历完v的所有子节点后,发现low[v]=dfn[v],说明u的父亲边(u,v)为割边。
void tarjan(int x)
{
v[x]=1;
Dfn[x]=Low[x]=time++;
for(int i=head[x];i;i=next[i])
{
if(!v[ver[i]])
{
p[ver[i]]=edge[i]; //记录父亲边
tarjan(ver[i]);
Low[x]=min(Low[x],Low[ver[i]]);
}
else if(p[x]!=edge[i]) //不是父亲边则更新
Low[x]=min(Low[x],Dfn[ver[i]]);
if(p[x]&&low[x]==dfn[x])
f[p[x]]=1; //为割边
}
}
3.点双连通分量
点双连通分支,在求割点的过程中就能把每个点双连通分支求出。建立一个栈,存储双连通分支。在搜索图时,每找到一条树枝边或后向边(非横叉边),就把这条边加入栈中。如果遇到某时满足DFS(u)<=Low(v),说明u是一个割点,同时把边从栈顶一个个取出,直到遇到了边(u,v),取出的这些边与其关联的点,组成一个点双连通分支。
if(dfn[u]==low[u])
{
scc++;
while(1) //记录每一个点属于的连通块
{
v=sta[top--];
instack[v]=0;
belong[v]=scc; //所取出的点即为双连通分支
if(v==u)
break;
}
}
}
4.边双连通分支。在求出所有的桥以后,把桥边删除,原图变成了多个连通块,则每个连通块就是一个边双连通分支。桥不属于任何一个边双连通分支,其余的边和每个顶点都属于且只属于一个边双连通分支。
5.一个有桥的连通图,如何把它通过加边变成边双连通图
首先求出所有的桥,然后删除这些桥边,剩下的每个连通块都是一个双连通子图。把每个双连通子图收缩为一个顶点,再把桥边加回来,最后的这个图一定是一棵树,边连通度为1。
统计出树中度为1的节点的个数,即为叶节点的个数,记为leaf。则至少在树上添加(leaf+1)/2条边,就能使树达到边二连通,所以至少添加的边数就是(leaf+1)/2。
void Tarjan(int u,int fa)
{
int i,v;
low[u]=dfn[u]=++cnt;
sta[++top]=u;
instack[u]=1;
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(i==(fa^1))
continue;
if(!dfn[v])
{
Tarjan(v,i);
low[u]=min(low[u],low[v]);
}
else if(instack[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
scc++;
while(1) //记录每一个点属于的连通块
{
v=sta[top--];
instack[v]=0;
belong[v]=scc;
if(v==u)
break;
}
}
}
for(i=1;i<=n;i++)
{
for(j=first[i];j!=-1;j=edge[j].next)
{
v=edge[j].v;
if(belong[i]!=belong[v])
degree[belong[i]]++; //degree为1则为leaf
}
}
int sum=0;
for(i=1;i<=n;i++)
if(degree[i]==1)
sum++; 统计leaf数
}
tarjan算法应用 割点 桥 双连通分量的更多相关文章
- tarjan算法(割点/割边/点连通分量/边连通分量/强连通分量)
tarjan算法是在dfs生成一颗dfs树的时候按照访问顺序的先后,为每个结点分配一个时间戳,然后再用low[u]表示结点能访问到的最小时间戳 以上的各种应用都是在此拓展而来的. 割点:如果一个图去掉 ...
- [Tarjan系列] Tarjan算法求无向图的双连通分量
这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...
- Tarjan算法求割点
(声明:以下图片来源于网络) Tarjan算法求出割点个数 首先来了解什么是连通图 在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点i到顶点j有路径相连(当然从j到i也一定有路径),则称 ...
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)
基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...
- 学习笔记--Tarjan算法之割点与桥
前言 图论中联通性相关问题往往会牵扯到无向图的割点与桥或是下一篇博客会讲的强连通分量,强有力的\(Tarjan\)算法能在\(O(n)\)的时间找到割点与桥 定义 若您是第一次了解\(Tarjan\) ...
- Tarjan算法与割点割边
目录 Tarjan算法与无向图的连通性 1:基础概念 2:Tarjan判断割点 3:Tarjan判断割边 Tarjan算法与无向图的连通性 1:基础概念 在说Tarjan算法求解无向图的连通性之前,先 ...
- 图的连通性——Tarjan算法&割边&割点
tarjan算法 原理: 我们考虑 DFS 搜索树与强连通分量之间的关系. 如果结点 是某个强连通分量在搜索树中遇到的第⼀个结点,那么这个强连通分量的其余结点肯定 是在搜索树中以 为根的⼦树中. 被称 ...
- Tarjan 算法求割点、 割边、 强联通分量
Tarjan算法是一个基于dfs的搜索算法, 可以在O(N+M)的复杂度内求出图的割点.割边和强联通分量等信息. https://www.cnblogs.com/shadowland/p/587225 ...
随机推荐
- oracle基本语句(第七章、数据库逻辑对象管理)
索引.实体化视图.簇.散列簇.序列.同义词 1.创建表 CREATE TABLE <表名>(<列名1> <数据类型>,……); CREATE GLOBAL TEMP ...
- scipy.sparse 稀疏矩阵
from 博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun 本文主要围绕scipy中的稀疏矩阵展开,也会介绍几种scipy之外的稀疏矩阵 ...
- php大文件分片上传插件
PHP用超级全局变量数组$_FILES来记录文件上传相关信息的. 1.file_uploads=on/off 是否允许通过http方式上传文件 2.max_execution_time=30 允许脚本 ...
- 给DEDECMS广告管理中增加图片上传功能
dedecms的广告管理功能稍微有点次,本文就是在dedecms广告管理原有的基础上增加广告图片上传功能. 安装方法,对应自己的dedecms版本下载对应的编码然后解压把里面的文件放在后台目录覆盖即可 ...
- mobx使用
1.mobx状态管理 安装:creact-react-app mobx action.store.reducer. action是一个函数,事件调用actions直接修改state,Actions是唯 ...
- mysql 普通用户与权限
1.创建用户 mysql> create user 'myself'@'%' identified by 'Myself'; Query OK, 0 rows affected mysql> ...
- 结合webpack使用vue-router
demo结构 webpack.config.js var path = require('path'); // const { VueLoaderPlugin } = require('vue-loa ...
- node.js入门学习(三)--npm
一.npm介绍 1)npm:node package manager是node.js默认的以js编写的软件包管理系统 官网:www.npmjs.com 文档:docs.npmjs.com 2)提到np ...
- 原生JS获取li中的内容
- BZOJ 2731 Luogu P3219 [HNOI2012]三角形覆盖问题 (扫描线)
题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=2731 (luogu)https://www.luogu.org/probl ...