首页 > 其他分享 >wsr_tarjan

wsr_tarjan

时间:2023-07-20 20:47:34浏览次数:39  
标签:tarjan 连通 返祖 结点 割点 wsr dfn 分量

Tarjan

首先是概念:


极大强连通分量:

不能再加入一点保持整个图强连通的图


强连通分量:

从任意一点能到达另一任意一点的图


Tarjan原理

  1. 树边 :在树上 (图中黑色边)

  2. 横插边 :从一棵子树到另一棵子树的边(图中绿色边)

3、 返祖边 :连到自己的祖先的边

image

观察图,我们可以注意到:

横插边不可能构成新的强连通分量

原因:若要构成强连通分量,左侧子树必定有连向右侧子树的边,在访问左子树时便会将 强连通分量 搜出,不会产生新的,所以在遍历时 无视 横插边即可

同时,对于一个强连通分量而言,

树中一定有一个结点是强连通分量中深度最浅的结点

image

如图,如果一个点能成为 强连通分量 中深度最浅的结点,一定不能有返祖边跨越过该点。

所以对于右子树中的强连通分量, 绿色星星 所在的位置就是它强连通分量中深度最浅的结点


重点!!!!

image

对于每个点,我们记录一个 dfn[x] 为当前结点 x 的 dfs 序,再记录一个 low[x] 为 当前结点向下搜索后仅向上一次,能到达的 dfn 值最小的结点

为什么呢?

其实在强连通分量中这样搜索是没有问题的

但是在割点/割边中,这样做会 寄

(下面会讲

 

image image844×536 98.2 KB

 

 

image image666×577 10.9 KB

 

此处图片来自dalao @hyf

可以代入理解一下

PS:单个点也是强连通分量


Tarjan代码实现

void tarjan(int x){
	dfn[x]=low[x]=++top;
    vis[x]=1;//是否在栈里 为1是在栈内
    q.push(x);
    for(int i=head[x];i!=-1;i=a[i].next){
        if(!dfn[a[i].to]){
			tarjan(a[i].to);
            low[x]=min(low[x],low[a[i].to]);
        }else if(vis[a[i].to]&&dfn[a[i].to]<low[x]){//避免先前已经搜过部分
            low[x]=dfn[a[i].to];
        }
    }
    if(dfn[x]==low[x]){
        cnt++;
        while(q.top()!=x){
            vis[q.top()]=0;
            b[q.top()]=cnt;
            q.pop();
        }
        vis[x]=0;
        b[x]=cnt;
        q.pop();
    }
}

一个奇怪的算法

 

image image915×370 23.1 KB

 

↑ 一个死掉的算法

原因:复杂度不比Tarjan优,被Tarjan全部代替

坦白的说:这个不用会。

 

image image788×314 53.2 KB

 


定义


割点

删去这个点后无向图被分成多个部分


割边

删去这条边后无向图被分成多个部分


关于割点


图像

image

如图,这是一个割点的图例

回到 上面 说过的,割点在跳返祖边时不能跳过多个返祖边

就像右图中,如果跳过多个返祖边,会从割点上跳过

而有返祖边的点也可以是割点

如果连跳 割点将无法通过

dfn[x]==low[x] && 有一个孩子


具体判断割点

 

image image698×154 27.4 KB

 

如果 Low[v] > dfn[u] (其中v是孩子结点,u是割点)

则割点被删去后图仍然能连通

所以必须有 Low[v]<=dfn[u] 时

割点 u 才成立


关于割边

一条没有被返祖边跨越的边即为割边

非常的简单(


2-SAT


定义

  • 首先是 SAT 问题
  • SAT 是指同时满足多组条件的问题
  • 解法:暴力
  • 因为SAT问题已经被证明为了 NPC(NP完全) 问题,只能暴力做
  • 复杂度: 仅仅 O(nk)
  • 2-sat 是指每个同学仅提出两个条件的问题
  • 做法:建图连边,使用强连通分量
  • 复杂度:大概是 O(N+M)

例子

带入到具体的例子

假设有 A,B,C 三个同学,提出了一些对于甲、乙、丙的约束

A甲和乙性别相同甲和丙性别不同
B 乙不能是男的 丙和乙性别不同
C 丙不能是女的 丙和甲性别不同

 

image image828×586 9.19 KB

 

:male_sign: → 男

:female_sign: → 女

在赋值时,将所在的强连通分量的拓扑序较大的X赋值为1

而拓扑序较小的赋值为0

关于方形图

 

image image704×518 47.7 KB

 

建图方法:

  • 找到割点 x
  • 新建一个方点 m
  • 连接 x和m ,边权为 0
  • 将 m 和连通分量里面的点连边,边权为从割点到该点的最短路
  • 在方点处统计答案

标签:tarjan,连通,返祖,结点,割点,wsr,dfn,分量
From: https://www.cnblogs.com/Reply-/p/17569599.html

相关文章

  • LCA 离线tarjan算法
    tarjan算法是离线算法,它必须先将所有的要查询的点对存起来,然后在搜的时候输出结果。tarjan算法很经典,因为算法的思想很巧妙,利用了并查集思想,在dfs下,将查询一步一步的搜出来。伪代码如下:可以看到,对于我们已经保存好的查询,假设为(u,v),u为此时已经搜完的子树的根节点,v的位置就只有两种......
  • tarjan 学习笔记
    tarjan学习笔记求解强联通分量我们从一个点开始建立dfs树,有如下四种边:树边若\(u\)到\(v\)有边,且满足\(v\)没有被访问过,则这条边为树边返祖边若\(u\)到\(v\)有边,且满足\(v\)已被访问过,则这条边为返祖边横叉边若\(u\)到\(v\)有边,且满足\(u\)和......
  • 【学习笔记】Tarjan
    前言:凡事都得靠自己--bobo催隔壁K8Hen天了让他写Tarjan的学习笔记,但貌似还没有动静,所以决定自己写一个。正文本文配套题单:14.图论-tarjan(强连通分量、割点、割边)前置知识熟练使用链式前向星强连通、强连通图、强连通分量的定义(详见oi-wiki,这里不再赘述)如图......
  • BZOJ 2730: [HNOI2012]矿场搭建 tarjan割点
    2730:[HNOI2012]矿场搭建TimeLimit: 10Sec  MemoryLimit: 128MBSubmit: 2010  Solved: 935[Submit][Status][Discuss]Description煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口......
  • BZOJ 2140: 稳定婚姻 tarjan
    2140:稳定婚姻TimeLimit: 2Sec  MemoryLimit: 259MBSubmit: 764  Solved: 355[Submit][Status][Discuss]Description我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关。25......
  • BOZJ 1123: [POI2008]BLO tarjan求割点
    1123:[POI2008]BLOTimeLimit: 10Sec  MemoryLimit: 162MBSubmit: 1140  Solved: 505[Submit][Status][Discuss]DescriptionByteotia城市有n个townsm条双向roads.每条road连接两个不同的towns,没有重复的road.所有towns连通。Input输入n<=100000m<=5......
  • [算法学习笔记] Tarjan LCA
    在讲解之前,我们先来看一道模板题:LuoguP3379最近公共祖先(LCA)WhatisLCALCA,即最近公共祖先。什么意思呢,我们举个例子:将就着看吧qwq这棵树中,0为根节点。若规定\(LCA(x,y)\)为\(x,y\)的最近公共祖先,则\(LCA(5,6)=2;LCA(4,3)=1;LCA(5,3)=0\)。还有很多,这里不一一列举了。最......
  • 无向图Tarjan浅谈
    NoteTarjanPart1怎么做自己看书Part2为什么是对的证明:搜索树是一棵树由于每个节点都只会访问一次,回溯一次,故会访问(n-1)*2条边,只取访问时的边,即n-1条,可以构成树证毕。证明:在一个简单环上的一条边不可能是桥如果破除这条边,只能把环断成链,不会损坏连通性。证毕。证明......
  • POJ2117 Electricity 题解 tarjan点双连通分量 割点
    题目链接:http://poj.org/problem?id=2117题目大意:给定一个由\(n\)个点\(m\)解题思路:tarjan,判断\(u\)的子节点有几个\(v\)满足\(low[v]\gedfn[u]\)就是答案,但是同时如果\(u\)不是这个dfs树的根节点,个数还要加\(1\)。示例程序1(C++11,POJ不支持):#include<bits/stdc++.h>......
  • P2860 [USACO06JAN]Redundant Paths G 题解 tarjan边双连通分量
    题目链接:https://www.luogu.com.cn/problem/P2860题目大意:给定一个无向连通图,求至少加几条边,能使其变成一个边双连通图。解题思路:边双连通分量缩点后计算度数为\(1\)的节点个数,假设有\(cnt\)个,则答案为\((cnt+1)/2\)。示例程序:#include<bits/stdc++.h>usingnamespacestd;......