Tarjan的证明(bushi)

tarjan算法原理介绍 证明比较繁琐,仔细检查了应该没有大错,记录一下证明过程。 强连通分量定义: 在有向图中,强连通分量的定义是:有向图的某个子图,其中任意两个点之间可以互达。 强连通分量的定理: 定理1:一个完整的强连通分量一定包含在一棵深度优先搜索树中。 定理2:子图是强连通分量子图中的每一条路径都归属于一个环状(除非只有一个点)。 证明:根据强连通分量的定义,任意两个点之间可以互达,所以等价于 阅读详情

以下是lyn学长在今天为我们这些经冰镪酱讲解Tarjan模板时所用的PPT

第一页

前方高能请注意

第二页

将复杂图上问题转化为相对简单的特殊图上问题。

        有向图:找强连通分量(scc)

                缩scc?

                        DAG

无向图:找割点、桥(点双、边双)

        缩点双、边双?

                圆方树,树

———————————————————————————————————————————然后就是一大堆概念……不说了

但是呢,有一个问题,很是引起了我的兴趣:

给一个有向图,如果你手动标记了一个点,那么这个点以及它所能到达的所有点都被标记。

问:

1. 最少手动标记多少个点使得所有点被标记

2. 最少加入多少条有向边使得只需要手动标记任意一个点就能标记所有点

n≤100000

很好想对不对,反正我们九个人讨论了将近一个小时

答案的确不难

1.入度为0的点的个数

2.max(入度为0的点的个数,出度为0的点的个数),既然n≤100000,那么数据范围其实也是无所谓的对吧?(bushi

思路分析

首先一般来看,是当前的图来说的话不好做,我们既然已经学了Tarjan算法,我们就可以先把他缩图成一个有向无环图来做(这是final版本)

假设转换为之后的有向无环图总共有p个起点和q个终点,可以给图中的每一个起点进行标记,那么图中的其余点都是可以被标记的,而题目中要求解至少添加多少条边,相当于是至少给多少个起点进行标记会使其余所有点可以被标记,所以至少需要给p个起点标记,也即第一问的答案是p。

对于第二问其实问的是我们需要在原图中添加多少条边使其变成一个强连通分量(图中任意两点可以相互到达),我们将原图转换为有向无环图之后需要添加至少max(p,q)条边使其变为一个强连通分量,这个结论比较重要,但是证明的过程很难,我们记住这个结论就可以了,我写在后面就可以了。记住吧,题目的核心是使用tarjan算法将原图转换为有向无环图,包含两个步骤:① 求解强连通分量,在dfs的过程中求解出每一个强连通分量并且将强连通分量中的所有点标记在对应的强连通分量的编号中;② 缩点,遍历所有节点,然后遍历当前点的所有邻接点,然后统计每一个强连通分量整体的入度和出度,最后遍历一下每一个强连通分量计算入度和出度为0的个数,输出答案即可。

证明:

证明如下:

不妨设p ≥ q (如果p < q那么可以将图的每条边反个向即可)。如果q = 1 ,那么将出度为0 的点连p 条边到p 个入度为0 的点,显然是一种方案,并且,如果只连少于p 条边,那么入度为0 的p 个点里必然有其中某个点没有入边,那么这个点将是到不了的,矛盾;如果q > 1 ,则必然能找到q 个入度为0 的点,使得这些点逐个可以到达q 个出度为0 的点,且一一对应。如若不然,则说明p 个入度为0 的点都走不到某个出度为0 的点,这与缩点后的图是有向无环图矛盾。挑一个出度为0 的点u 和入度为0的点v ,连一条边u → v ,这就会把规模( p , q ) 的问题转为规模( p − 1 , q − 1 ) 的问题,后者的解是max ⁡ { p , q } − 1 ,所以原问题的解的上界就是max ⁡ { p , q } = p 。如果解小于p ,同样会使得至少一个入度0 的点到不了,矛盾,即原问题得证(完结撒花)。

代码如下

//求割点
void dfs(int u,int fa)
{
	low[u] = dfn[u] = dfs_clock ++;
	int c = 0;
	for(int i = head[u];i;i = nxt[i])
	{
		int v = to[i];
		if(!dfn[v])
		{
			dfs(v,u);
			c ++;
			low[u] = min(low[u],low[v]);
			if(low[v] >= dfn[u])
			cut[u] = 1;
		}
		else
		if(dfn[v] < dfn[u] && v != fa)
		low[u] = min(low[u],dfn[v]);
	}
	if(c == 1 && fa == 0)
	cut[u] = 0;
}
int main() 
{
    cin >> n;
    memset(h, -1, sizeof h);
    for (int i = 1;i <= n;i ++) 
	{
        int t;
        while(cin >> t, t) 
		add(i, t);
    }
    for(int i = 1;i <= n;i ++) 
        if(!dfn[i])
            tarjan(i);
    for(int i = 1;i <= n;i ++) 
        for(int j = h[i];j;j = ne[j]) 
		{
            int k = e[j];
            int a = id[i], b = id[k];
            if(a != b) 
			{
                dout[a]++;
                din[b]++;
            }
        }
    int a = 0, b = 0;
    for(int i = 1;i <= scc_cnt;i ++) 
	{
        if(!din[i]) 
		a++;
        if(!dout[i]) 
		b++;
    }
    cout << a;
    if (scc_cnt == 1)
    cout << 0;
    else
    cout << max(a,b);
    return 0;
}

自测样例似乎是过了,对不对再说吧,在调吧

tarjan算法 tarjan算法介绍 阅读详情

相关推荐

【Photoshop JSX脚本】强大的事件监听器脚本 - event_listener.jsx

新手第一次了解的事件监听一定是ScriptingListener.8bi插件,如果你对此插件有了基本运用,那么现在了解一款更方便的时间监听脚本event_listener.jsx。不再像ScriptingListener.8bi插件那样晦涩难懂。 1、准备event_listener.jsx文件到 F:\Program Files\Adobe Photoshop 2020\Presets\...

Greless的后花园 8208

tarjan的部分讲解及有关证明解答

LCA(Tarjan) 分类,使每个结点都落到某个类中,到时候只要执行集合查询,就可以知道结点的LCA了。 对于一个结点u.类别有: 以u为根的子树、除类一以外的以f(u)为根的子树、除前两类以外的以f(f(u))为根的子树、除前三类以外的以f(f(f(u)))为根的子树…… 类一的LCA为u,类二为f(u),类三为f(f(u)),类四为f(f(f(u)))。这样的分类看起来好像并不困难。 但关...

吾谁知 433

避坑指南:时间序列互相关分析(CCF)常见的5个误用场景

本文详细解析了时间序列互相关分析(CCF)中常见的5个误用场景,包括忽视平稳性检验、混淆同期相关与因果关联、误读滞后阶数、忽略自相关干扰以及样本量不足等问题。通过实际案例和技术建议,帮助数据分析师避免这些陷阱,确保CCF分析的准确性和可靠性。

weixin_29064009的博客 428

Tarjan算法流程和简要证明

声明:一下许多内容摘自: 北京大学暑期课《ACM/ICPC竞赛训练》强连通分支、桥和割点 北京大学信息学院 郭炜不建议初学者直接看这篇博文 可以先了解一下Tarjan算法的具体流程,再来看证明。 推荐:全网最!详!细!tarjan算法讲解强连通分量如果有向图G的每两个顶点都强连通,称G为强连通图。 非强连通图有向图的极大强连通子图,称为强连通分量。算法流程DFN[i]表示 遍历到 i 点时是

ONE MORE TRY 2124

Windows系统3D Gaussian Splatting环境搭建全攻略:从零开始到成功运行

本文详细介绍了在Windows系统上搭建3D Gaussian Splatting环境的完整流程,包括CUDA 12.6安装、Anaconda环境配置、代码获取与依赖安装等关键步骤。针对Windows平台特有的环境配置问题,提供了实用的解决方案和常见错误排查方法,帮助开发者快速实现3D Gaussian Splatting的成功运行。

weixin_30832143的博客 454

【AI蛋白预测实战】零门槛在Colab上运行AlphaFold2全流程解析

本文为零基础用户提供了在谷歌Colab平台上运行AlphaFold2进行蛋白质结构预测的完整实战指南。通过ColabFold项目,用户无需本地高性能硬件,即可免费利用云端GPU完成从序列输入到3D结构生成和结果可视化的全流程,大幅降低了AI蛋白预测的技术门槛。

mqtt6iot的博客 913

对求有向图强连通分量的tarjan算法原理的一点理解

Tarjan算法正确性的详细证明

naturerun的博客 981

BL0910-从零到一:多路交/直流电能计量的实战配置与校准

本文详细介绍了BL0910芯片在多路交直流电能计量中的实战应用。从硬件连接、SPI通信配置,到软件初始化、核心寄存器设置,再到偏置与增益校准,提供了完整的配置与校准指南。文章重点阐述了直流测量模式的切换要点及数据读取的工程化处理,帮助开发者快速实现高精度、多通道的电能监控方案。

rice5的博客 565

Tarjan实现的逻辑推导

//------------------------------------------------- 膜拜大佬文章:tarjan算法原理介绍_zakheav的博客-优快云博客_tarjan算法证明 关于tarjan的正确性证明已经困恼了我好久 今天下定决心 去深究原理。 看到大佬的文章 感觉茅塞顿开特此记录下来 //-------------------------------------------------

Lee_2002的博客 707

​苹果开发者账号推送证书配置详细指南​

推送证书的配置是iOS应用实现消息推送的核心步骤。通过生成证书、配置描述文件、集成到服务器三大环节,开发者可快速为App启用APNs服务。建议优先使用更灵活的APNs Auth Key替代传统证书,以减少维护成本。确保拥有有效的苹果开发者账号(个人/公司账号),年费已缴纳。

2327

Qt图形视图框架实战:QGraphicsScene、QGraphicsView与QGraphicsItem的深度应用

本文深入解析Qt图形视图框架的核心组件QGraphicsScene、QGraphicsView与QGraphicsItem的实战应用。通过“舞台、镜头与演员”的比喻,清晰阐述了三者的协作关系,并详细介绍了场景管理、多视图同步、交互增强、自定义图形项绘制与性能优化等高级技巧,帮助开发者高效构建复杂的交互式图形界面。

weixin_29251337的博客 263

Tarjan算法求LCA正确性大致证明

每次只要将一个子树遍历完,就将其合并到其直接父亲节点上,因为后面的几个分叉出的子树中的点,与在以遍历完的子树中的点的LCA一定是它们的直接父亲节点(图中是节点1)。但是,这样会增加时间复杂度,因为如果先遍历,后更新,所有在以当前节点为根的子树中的点都会被算2次,一次在当前节点,一次在询问中的另一个节点。对于所有在以2号点为根的子树中的点,如果要求它们与一个在以3至6号点为根的子树中的点的LCA,那么结果都一定是1,因为这两个点都和2至6节点一样从1号节点开始分在了两个不同的子树中。

shenshi6666的博客 379

交叉熵损失函数基本概念及公式

对于二分类问题,模型的输出通常是一个标量,表示样本属于正类的概率。因此,在二分类的交叉熵损失函数中,我们只需要考虑一个概率值,即模型预测为正类的概率。具体来说,当真实标签为1时,我们关注模型预测为正类的概率;当真实标签为0时,我们关注模型预测为负类的概率。因此,二分类的交叉熵损失函数可以表示为:其中,y 表示真实标签,取值为 0 或 1;p 表示模型预测为正类的概率。而对于多分类问题,模型的输出通常是一个向量,表示样本属于各个类别的概率。因此,在多分类的交叉熵损失函数中,我们需要考虑所有类别的概率。

qlkaicx的博客 1万+

Tarjan 算法学习笔记(超详细)

对于一张有向图\(S\)的子图\(V\),满足\(V\)内的点两两之间可达,并且不存在一个子图\(G\)使得,通俗的讲就是无法继续扩张的两两可达的子图。对于无向图(注意:图不一定连通),割边的定义为:去掉这条边后图的连通块数量增加。对于无向图(注意:图不一定连通),割点的定义为:去掉这个点后图的连通块数量增加。

weixin_41496326的博客 170

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

tarjan算法,桥判断,割点判断

算法背景 Tarjan算法是由Robert Tarjan(罗伯特·塔扬,不知有几位大神读对过这个名字) 发明的求有向图中强连通分量的算法。 预备知识点 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强...

qq_43227036的博客 2361

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

强连通分支之Tarjan 算法

比Kosaraju算法更神奇,只需要一次DFS就可以获得强连通分支。其原理是每一个强连通分支,均包含在DFS树的某个子树中,只要找到这个子树的树根,再逐一将该连通分支所有结点取出即可。 数据结构: 1)        栈,DFS访问结点时入栈,某个强连通分支访问结束后其所有结点出栈,以下需要证明当刚好访问结束某个强连通分支时,其所有结点均在栈顶; 2)        数组dfn,DFS过程中

白水白水的专栏 1789

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Tarjan算法 + kosaraju小证明哟

看的别人写的 很好,摘要几点的啦~~~:一.概念:1.强连通:如果在一个有向图上两个结点u,v他们相互之间至少存在一条通路,则他们是强连通的.2.强连通图:如果有向图G任意两天都强连通,则G是强连通图.3.强连通分量:有向非强连通图的极大强连通子图.二.O(N+M)的Trajan, 特么的Trajan是个甜菜1.Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。定义:DFN(u

流水不争先 1313

tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明

“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----《膜你抄》 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一直没有时间学习。这两天好不容易学会了,写篇博客,也算记录一下。 一、tarjan求强连通分量 1、什么是强连通分量? 引用来自度娘的一句话: “有向图强连通分量:在有向图G中,如...

weixin_30273931的博客 443

Tarjan算法详解

       在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。如下图中,强连通分量有:{1,2,3,4},{5},{6}       Tarjan算法是基于对图深度优先搜索的算法...

刘伟的博客 1万+

Lengauer-Tarjan算法的相关证明

Lengauer-Tarjan算法的相关证明 0. 约定 为简单起见,下文中的路径均指简单路径(事实上非简单路径不会对结论造成影响)。 \(V\)代表图的点集,\(E\)代表图的边集,\(T\)代表图的DFS树。 \(a \to b\)代表从点\(a\)直接经过一条边到达点\(b\)(即\((a, b) \in T\)), \(a \leadsto b\)代表从点\(a\)经过某条路径到达点\(b...

weixin_30955341的博客 355

三种tarjan算法(上)

前几天做了一下有关tarjan算法的专题。这篇算是做一个总结吧。 求强连通分量求无向图的割和桥最近公共祖先 求强连通分量  基本概念:       强连通是有向图才有的概念。一个有向图是强连通的是对于每个有序对 u,v,存在一条从 u到v  的路径。一个有向图的强连通分量是指它的极大连通子图。就是你可以从 a地走到 b 地,同样可以从b地走到a地,a,b就是连通的。

nothi的专栏 7296

Tarjan算法介绍

一种由Robert Tarjan提出的求解有向图强连通分量的线性时间的算法。 Tarjan与无向图连通性 ·几个定义 给定无向图G=(V,E)G=(V,E)G=(V,E) 如果割掉点x,图中的连通块数量增加,则称x为G的割点 如果割掉边e,图中的连通块数量增加,则称e为G的桥或割边 ·时间戳 在图的深度优先搜索中,按照每个节点的访问顺序所给每个点编的号,该编号叫做“时...

cdy1206473601的博客 1188

迪杰斯特拉(Dijkstra)算法描述及其正确性证明

Dijkstra算法描述及其正确性证明

softee的专栏 2万+

图的连通性问题之tarjan算法

Tarjan算法一种由Robert Tarjan提出的求解有向图强连通分量的线性时间的算法。 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。 定义dfn(u)为节点u搜索的次序编号,low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号。 当dfn(u)

cax1165 2811

关于tarjan算法

tarjan算法其实是在dfs基础上维护一个标志值来判断当前点是否是某种特殊点,而学习tarjan算法,通过tarjan的DEPTH-FIRST SEARCH AND LINEAR GRAPH ALGORITHMS学习好像并不是什么好的选择…但是读一读dalao的论文还是挺有趣的,本文对tarjan的论文进行简单翻译和补充我自己的理解。 一些符号和基础定义: 对于图G=(V,E)G=(V,E)G=(V,E)来说。 路径p:v⇒∗wp:v\stackrel{*}{\Rightarrow}wp:v⇒∗w表示存在

一个蠢人的博客 475
上一篇: 图论的总结(知足)(板子)
下一篇: 集训总结(新春前的诗)(Final七步曲版)
MaydayMerlin
博客等级 码龄3年 346粉丝 29原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值