割点的定义:

  感性理解,所谓割点就是在无向连通图中去掉这个点和所有和这个点有关的边之后,原先连通的块就会相互分离变成至少两个分离的连通块的点。

   举个例子: 图中的4号点就是割点,因为去掉4号点和有关边之后连通块{1,2,3} {5} {6}就相互分离了。

图片来自:一篇写的较好的blog:https://www.cnblogs.com/jason2003/p/7603886.html

  

Tarjan算法求割点:

  有好多个Tarjan算法,不要傻傻分不清~~

  其实和有向图求强连通分量的Tarjan算法差不多啦,也用到了dfn和low。

  因为是无向连通图,所以横向边是没有意义的,(有反向边的存在)。

  dfn[u]:u在搜索树中被遍历到的次序号(时间戳)。

  low[u]:u或u的子树中的结点经过最多一条后向边能追溯到的最早的树中结点的次序号(dfn),有点懵,先不管他,感性理解就是通过边到达的点的最小时间戳。

割点判断条件:

  ①:若u为树的树根,那么只要u有两个及以上的子节点,那么只要u点消失,子节点所在的连通块就会分离了。

如果只有一个子节点,那么u消失之后还剩下那个子节点的连通块,仍是一个并不是多个。

  ②:若u不为树根,v不为u的父结点,当dfn[u]<=low[v]时,u就为割点,由该式子的含义可得,v以及v的子树最多只能到达u结点,

不能到达u的祖先,此时删掉u,那么(v及v的子树)和(u的祖先)就会相互分离了,自然u就是割点。

  求割点时若(u,v)为后向边,v不为u的父结点,low[u]=min{low[u],dfn[v]},里面一定要写dfn[v],不能写low[v]。

原因详见:https://www.luogu.org/blog/ztyluogucpp/solution-p3388

割点模板:

  L3388 【模板】割点(割顶):https://www.luogu.org/problemnew/show/P3388

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define maxn 100009
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+(ll)(ch-'');ch=getchar();}
return x*f;
}
int head[maxn],dfn[maxn],low[maxn],point[maxn];
int n,m,k,ans,cnt,id,tot,root;
struct edge
{
int to,nxt;
}p[maxn<<]; void add(int x,int y)
{
++cnt,p[cnt].to=y,p[cnt].nxt=head[x],head[x]=cnt;
} void Tarjan(int u,int fa)
{
dfn[u]=low[u]=++id;
int child=;
for(int i=head[u];i;i=p[i].nxt)
{
int v=p[i].to;
if(!dfn[v])
{
Tarjan(v,u);
low[u]=min(low[u],low[v]);
if(u!=root&&low[v]>=dfn[u])
point[u]=;
if(u==root&&++child>=)
point[u]=;
}
else
low[u]=min(low[u],dfn[v]);
} }
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read(),m=read();
for(int i=;i<=m;i++)
{
int x=read(),y=read();
add(x,y),add(y,x);
}
for(int i=;i<=n;i++)
if(!dfn[i])
root=i,Tarjan(i,i);
for(int i=;i<=n;i++)
if(point[i])
tot++;
printf("%d\n",tot);
for(int i=;i<=n;i++)
if(point[i])
printf("%d ",i);
fclose(stdin);
fclose(stdout);
return ;
}

割边的定义:

  和割点的定义类似,只不过是把去掉点以及与点有关的边改成了去掉这条边看是否连通就行啦。

Tarjan算法求割边:

  和求割点只有一点点小区别...

   因为有可能存在重边的问题,所以要将一条无向边拆为两条编号一样的有向边,用邻接表进行储存,在判断(u,v)是否为后向边的时候要注意判断是树枝边的反向边还是新的一条边。

割边判断条件:

  dfn[u]<low[v],不可以取等号,因为取等号意味着v及v的子树能够到达结点u,那么(u,v)这条边自然就不是割边了。

  

割边模板:

  L1656 炸铁路:https://www.luogu.org/problemnew/show/P1656

  裸的割边模板,虽然不需要判断重边但是还是加上比较好,再用优先队列维护一下答案就可以了。

  判断是否是树枝边的反向边的时候只需要判断vis[i^1]是否等于1就行了,因为是这样判断的,所以在建边的时候cnt必须从1开始,因为0^1=0,并不会得到1这条反向边。

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
#define INF 0x3f3f3f3f
#define maxn 159
#define maxm 5009
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+(ll)(ch-'');ch=getchar();}
return x*f;
}
priority_queue<pair<int,int> >q;
int head[maxn],dfn[maxn],low[maxn];
bool vis[maxm<<];
int n,m,k,ans,tot,id,cnt=;
struct edge
{
int to,nxt;
}p[maxm<<]; void add(int x,int y)
{
p[++cnt]={y,head[x]},head[x]=cnt;
} void Tarjan(int u)
{
dfn[u]=low[u]=++id;
for(int i=head[u];i;i=p[i].nxt)
{
if(vis[i^])
continue;
int v=p[i].to;
vis[i]=;
if(!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
if(dfn[u]<low[v])
q.push(make_pair(-min(u,v),-max(u,v)));
}
else
low[u]=min(low[u],dfn[v]);
}
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read(),m=read();
for(int i=;i<=m;i++)
{
int x=read(),y=read();
add(x,y),add(y,x);
}
for(int i=;i<=n;i++)
if(!dfn[i])
Tarjan(i);
while(q.size())
{
printf("%d %d\n",-q.top().first,-q.top().second);
q.pop();
}
fclose(stdin);
fclose(stdout);
return ;
}

    

  

Tarjan求割点(割顶) 割边(桥)的更多相关文章

  1. 洛谷P3388 【模板】割点(割顶)(tarjan求割点)

    题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...

  2. Tarjan求割点和桥

    by szTom 前置知识 邻接表存储及遍历图 tarjan求强连通分量 割点 割点的定义 在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多, ...

  3. tarjan求割点与割边

    tarjan求割点与割边 洛谷P3388 [模板]割点(割顶) 割点 解题思路: 求割点和割点数量模版,对于(u,v)如果low[v]>=dfn[u]那么u为割点,特判根结点,若根结点子树有超过 ...

  4. $割点割顶tarjan$

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

  5. tarjan求割点割边的思考

    这个文章的思路是按照这里来的.这里讨论的都是无向图.应该有向图也差不多. 1.如何求割点 首先来看求割点.割点必须满足去掉其以后,图被分割.tarjan算法考虑了两个: 根节点如果有两颗及以上子树,它 ...

  6. UESTC 900 方老师炸弹 --Tarjan求割点及删点后连通分量数

    Tarjan算法. 1.若u为根,且度大于1,则为割点 2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边) 3.若low[v]>dfn[u], ...

  7. poj_1144Network(tarjan求割点)

    poj_1144Network(tarjan求割点) 标签: tarjan 割点割边模板 题目链接 Network Time Limit: 1000MS Memory Limit: 10000K To ...

  8. POJ 1144 Network(无向图的割顶和桥模板题)

    http://poj.org/problem?id=1144 题意: 给出图,求割点数. 思路: 关于无向图的割顶和桥,这篇博客写的挺不错,有不懂的可以去看一下http://blog.csdn.net ...

  9. POJ 1144 Network(Tarjan求割点)

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12707   Accepted: 5835 Descript ...

随机推荐

  1. python中的装饰器迭代器生成器

    装饰器: 定义:本质是函数(装饰其它函数) 为其它函数添加附加功能 原则: 1 不能修改被装饰函数源代码    2 不修改被装饰函数调用方式 实现装饰器知识储备: 1 函数即‘’变量‘’ 2 高阶函数 ...

  2. 【SVN】svn 查看项目的 svn 服务器地址目录(脱机状态下)

    #事故现场: 在无法连接到svn服务器地址的情况下,查看本地项目的svn的服务器地址目录: #事故分析 因为无法连接svn服务器,所以只能通过svn在本地存储的信息来获取svn的地址路径信息: #解决 ...

  3. 第九节:JWT简介和以JS+WebApi为例基于JWT的安全校验

    一. 简介 1. 背景 传统的基于Session的校验存在诸多问题,比如:Session过期.服务器开销过大.不能分布式部署.不适合前后端分离的项目. 传统的基于Token的校验需要存储Key-Val ...

  4. 第四节:SignalR灵魂所在Hub模型及再探聊天室样例

    一. 整体介绍 本节:开始介绍SignalR另外一种通讯模型Hub(中心模型,或者叫集线器模型),它是一种RPC模式,允许客户端和服务器端各自自定义方法并且相互调用,对开发者来说相当友好. 该节包括的 ...

  5. JGUI源码:Accordion鼠标中键滚动和手机端滑动实现(2)

    本文是抽屉组件在PC端滚动鼠标中键.手机端滑动时,滚动数据列表实现方法,没有使用iscroll等第三方插件,支持火狐,谷歌,IE8+等浏览器. 演示在:www.jgui.com Github地址:ht ...

  6. [物理学与PDEs]第3章习题6 Lagrange 坐标下的一维理想磁流体力学方程组的数学结构

    试讨论 Lagrange 形式下的一维理想磁流体力学方程组 (5. 33)-(5. 39) 的类型. 解答: 由 (5. 33), (5. 39) 知 $$\bex 0=\cfrac{\p p}{\p ...

  7. [译]Ocelot - Claims Transformation

    原文 用户授权后才能使用此功能. 用户获得授权后claims将被发送到claims transformation中间件.用户授权后,我们首先调用claims to headers middleware ...

  8. ch03 课下作业——缓冲区溢出漏洞实验

    一.实验简介: 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭 ...

  9. 4. SpringBoot —— 单元测试

    首先在pom文件中引入spring-boot-starter-test <dependency> <groupId>org.springframework.boot</g ...

  10. nslookup get public/external IP

    nslookup myip.opendns.com resolver1.opendns.com Server: resolver1.opendns.comAddress: 208.67.222.222 ...