tarjan知识点梳理
tarjan在图论中还是挺重要的.这里就简要的梳理一下tarjan的知识点.
tarjan算法与无向图连通性.
首先说一下图中割点和桥的定义.
桥:也称割边,定义类似,在无向图中,若去掉某条边,导致整张图不连通,则该边为割边.
割点:在无向图中,若去掉某个点,导致整张图不连通,则该点为割点.
其他的什么基础知识就不多说了,这里给出桥和割点的判定法则.
割边:dfn[x]<low[y].
感性的理解下,low[y]说明y向下走,没办法通过非树边到达x及以上的点.代码中的小细节就是tarjan时记录过来的边,防止重边对答案的影响.
割边:dfn[N],low[N],bridge[N],num;
inline void tarjan(int x,int in_edge)
{
dfn[x]=low[x]=++num;
for(int i=link[x];i;i=a[i].next)
{
int y=a[i].y;
if(!dfn[y])
{
tarjan(y,i);
low[x]=min(low[x],low[y]);
if(low[y]>dfn[x]) bridge[i]=bridge[i^1]=true;
}
else if(i!=(in_edge^1)) low[x]=min(low[x],dfn[y]);
}
}
割点:
1.若x不是搜索树的根结点,则满足dfn[x]<=low[y].(感性的理解,y只能到达x,无法与x以上的点取得联系)
2.若x是搜索树的1根结点,则满足至少存在两个以上节点才行.(根只有一个儿子显然不行.)
割点:num,dfn[N],low[N],vis[N];
inline void tarjan(int x)
{
dfn[x]=low[x]=++num;
int flag=0;
for(int i=link[x];i;i=a[i].next)
{
int y=a[i].y;
if(!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
flag++;
if(x!=root||flag>=2) vis[x]=1;
}
}
else low[x]=min(low[x],dfn[y]);
}
}
之后是无向图的双连通分量.
点双联通图:若一个图中不存在割点,则称该图是点双联通图.
点双联通分量:无向图中的极大点双连通图.
边双联通图:若一个图中不存在桥,则称该图是边双联通图.
边双连通分量:无向图中的极大边双联通图.
先讨论边双的情况(因为简单).
判定:一个图是边双连通图的充要条件,图中任意一条边都至少存在一个简单环中.
很显然吧,若不在环中,则该边连接的两个点就断开了,则存在割边,不符合定义.
给出边双联通分量,即缩点的代码:
inline void tarjan(int x,int in_edge)
{
dfn[x]=low[x]=++num;
for(int i=link[x];i;i=a[i].next)
{
int y=a[i].y;
if(!dfn[y])
{
tarjan(y,i);
if(low[y]>dfn[x]) bridge[i]=bridge[i^1]=true;
}
else if(i!=(in_edge^1)) low[x]=min(low[x],dfn[y]);
}
}
inline void dfs(int x)
{
c[x]=dcc;
for(int i=link[x];i;i=a[i].next)
{
int y=a[i].y;
if(c[y]||bridge[i]) continue;
dfs(y);
}
}
main函数内:
for(int i=1;i<=n;++i) if(!c[i]) dcc++,dfs(i);
for(int i=2;i<=tot;++i)
{
int x=a[i^1].y,y=a[i].y;
if(c[x]!=c[y]) add_c(c[x],c[y]);
}
点双连通分量的判定(至少满足一个):
1.图的顶点数不超过2.
2.图中任意两个节点都同时包含在至少一个简单环中.
证明略过.....(还是太菜了..)
点双的代码:
inline void tarjan(int x)
{
dfn[x]=low[x]=++num;
stack[++top]=x;
if(x==root&&link[x]==0)
{
dcc[++cnt].push_back(x);
return;
}
int flag=0;
for(int i=link[x];i;i=a[i].next)
{
int y=a[i].y;
if(!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
++flag;
if(x!=root||flag>=2) vis[x]=1;
cnt++;
int z=0;
while(z!=y)
{
z=stack[top--];
dcc[cnt].push_back(z);
}
dcc[cnt].push_back(x);
}
}
}
}
main函数内:
num=cnt;
for(int i=1;i<=n;++i) if(vis[i]) new_id[i]=++num;
tc=1;
for(int i=1;i<=cnt;++i)
{
for(int j=0;j<dcc[i].size();++j)
{
int x=dcc[i][j];
if(vis[x])
{
add_c(i,new_id[x]);
add_c(new_id[x],i);
}
else c[x]=i;
}
}
放一道边双缩点的题(码量很大啊...)
tarjan知识点梳理的更多相关文章
- Javascript重要知识点梳理
Javascript重要知识点梳理 一.Javascript流程控制 js中常用的数据类型 var关键字的使用 if – else if – else switch while for 二.Javas ...
- Memcache知识点梳理
Memcache知识点梳理 Memcached概念: Memcached是一个免费开源的,高性能的,具有分布式对象的缓存系统,它可以用来保存一些经常存取的对象或数据,保存的数据像一张巨大的HAS ...
- [独孤九剑]Oracle知识点梳理(十)%type与%rowtype及常用函数
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- [独孤九剑]Oracle知识点梳理(九)数据库常用对象之package
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- [独孤九剑]Oracle知识点梳理(八)常见Exception
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- [独孤九剑]Oracle知识点梳理(七)数据库常用对象之Cursor
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- [独孤九剑]Oracle知识点梳理(六)数据库常用对象之Procedure、function、Sequence
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- [独孤九剑]Oracle知识点梳理(五)数据库常用对象之Table、View
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- [独孤九剑]Oracle知识点梳理(四)SQL语句之DML和DDL
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
随机推荐
- 关于 CLAHE 的理解及实现
CLAHE CLAHE 是一种非常有效的直方图均衡算法, 目前网上已经有很多文章进行了说明, 这里说一下自己的理解. CLAHE是怎么来的 直方图均衡是一种简单快速的图像增强方法, 其原理和实现过程以 ...
- webpack4 使用babel处理ES6语法的一些简单配置
一,安装包 npm install --save-dev babel-loader @babel/corenpm install @babel/preset-env --save-devnpm ins ...
- Shell系列(12)- 预定义变量(5)
预定义变量 作用 $? 常用:最后一次执行的命令的返回状态. 如果这个变量的值为0,证明上一个命令正确执行:如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了 $$ ...
- 写SQL的套路
定义问题 转化问题 如要解决的问题是:查出每门课程成绩都大于80分学生的姓名,可以转化为:只要学生最小分数的课程大于80分,就是所有课程成绩都大于80分. 查询同名同姓学生名单并统计同名人数--> ...
- file_get_contents('php://input') 数据如何转换成数组
前台表单页:demo01.html 后台:demo01.php 输出结果: 备注:若前台通过Ajax的post提交过来的是json数据,需要对json数据进行解析:$data = json_decod ...
- html jquery操作
$(document).on('事件','元素',function(参数){ // 函数体 }) 元素获取方式:https://www.cnblogs.com/lixiuran/p/5316727.h ...
- web自动化:IE11运行Python+selenium程序
from selenium import webdriver # 运行此脚本前必须按要求修改注册表'''[HKEY_CURRENT_USER\Software\Microsoft\Internet E ...
- Javascript 常见的高阶函数
高阶函数,英文叫 Higher Order function.一个函数可以接收另外一个函数作为参数,这种函数就叫做高阶函数. 示例: function add(x, y, f) { return f( ...
- centos7.5离线安装Docker及容器运行报OCI runtime create failed 问题定位与解决
前言 接上篇 <记一次centos挂载ceph存储的坑> 服务器重做了centos7.5版本的操作系统,剩下就是安装docker,考虑yum安装耗时较长,我一般都是直接安装二进制版本doc ...
- java统一返回标准类型
一.前言.背景 在如今前后端分离的时代,后端已经由传统的返回view视图转变为返回json数据,此json数据可能包括返回状态.数据.信息等......因为程序猿的习惯不同所以返回json数据的格式也 ...