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;
}
}

放一道边双缩点的题(码量很大啊...)

364. 网络

tarjan知识点梳理的更多相关文章

  1. Javascript重要知识点梳理

    Javascript重要知识点梳理 一.Javascript流程控制 js中常用的数据类型 var关键字的使用 if – else if – else switch while for 二.Javas ...

  2. Memcache知识点梳理

    Memcache知识点梳理 Memcached概念:    Memcached是一个免费开源的,高性能的,具有分布式对象的缓存系统,它可以用来保存一些经常存取的对象或数据,保存的数据像一张巨大的HAS ...

  3. [独孤九剑]Oracle知识点梳理(十)%type与%rowtype及常用函数

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  4. [独孤九剑]Oracle知识点梳理(九)数据库常用对象之package

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  5. [独孤九剑]Oracle知识点梳理(八)常见Exception

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  6. [独孤九剑]Oracle知识点梳理(七)数据库常用对象之Cursor

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  7. [独孤九剑]Oracle知识点梳理(六)数据库常用对象之Procedure、function、Sequence

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  8. [独孤九剑]Oracle知识点梳理(五)数据库常用对象之Table、View

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  9. [独孤九剑]Oracle知识点梳理(四)SQL语句之DML和DDL

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

随机推荐

  1. ESP8266- 使用AT指令获取网络时间

    前言:很早就考虑过用 ESP8266 获取网络时间,以前都是用 ESP8266 刷机智云的 Gagent 固件,但无奈现在手头的 ESP-01 的 Flash 只有 1M,实在无法胜任.经过在网络上的 ...

  2. seo优化刷百度指数方法

    站长朋友们都听过"刷指数"这个概念,并且一直以来都有站长刷指数的现象.大家或为了提升网站数据,或为了满足排名的虚荣心,或为了与竞争对手抗衡,都或多或少研究过刷指数的原理和工具. 那 ...

  3. 队列,一种"公平"的数据结构

    路过一家奶茶店,由于生意火爆,门口的排着长长的队伍,先排队的人先买到奶茶,然后再轮到下一个,秩序井然.有没有一种数据结构能体现"先来后到"这种顺序呢? 当然有,那就是队列.先看一下 ...

  4. centos 7 & 6 优化脚本

    简单优化 ,未涉及安全优化,如有需求请自行修改脚本实现 1 #!/bin/bash 2 SysVer=`cat /etc/redhat-release | awk -F'release' '{prin ...

  5. IO流基本概念

    IO流主要分为两类 节点流:直接能够进行数据写入或读取的I0流.可以单独执行读写操作,但是功能比较单一,只能进行一些基本 的操作.例如:FileInputStream FileInputStream ...

  6. TypeScript 条件类型精读与实践

    在大多数程序中,我们必须根据输入做出决策.TypeScript 也不例外,使用条件类型可以描述输入类型与输出类型之间的关系. 本文同步首发在个人博客中,欢迎订阅.交流. 用于条件判断时的 extend ...

  7. apiserver源码分析——启动流程

    前言 apiserver是k8s控制面的一个组件,在众多组件中唯一一个对接etcd,对外暴露http服务的形式为k8s中各种资源提供增删改查等服务.它是RESTful风格,每个资源的URI都会形如 / ...

  8. java 从零开始手写 RPC (03) 如何实现客户端调用服务端?

    说明 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 写完了客户端和服务端,那么如何实现客户端和服务端的 ...

  9. ES6箭头函数(箭头函数和普通函数的区别)

    箭头函数 一个参数 // 只有一个参数 // f : 函数名称 // v : 函数参数 // v+v : 函数内容 let f=v=> v+v console.log(f(10)) //20 两 ...

  10. k8s学习笔记(2)- Rancher2.x部署springboot应用及高可用、扩容

    前言:上一篇介绍基于k3s环境,使用kubectl部署springboot简单项目应用,本篇介绍基于rancher2.x部署应用程序 1.上篇已部署一个springboot应用,我们可以通过ranch ...