Tarjan缩点(复习整理)

  • 若两顶点间至少存在一条路径,则称两个顶点强连通。
  • 若有向图G中每两个顶点都强连通,则称G为强连通图。
  • 非强连通图中的极大强连通子图称为强连通分量。
  • Tarjan算法本质上是一种dfs
  • dfn[i]:dfs时被遍历的次序(时间戳)。
  • low[i]:最早能回溯到的栈中的点的时间戳。
  • stack[i]:判断i点是否在栈中。
  • dindex:时间戳,stop:栈顶。
  • 强连通分量中的点在栈中必定是连续一段。如果一个点x无法回溯到在它之前且在栈中的点,假设它的头顶上还有点,这些点的low值为x或者连接点(连接的连接…)的low为x(如果不是,1.是自己,在此之前已经弹出;2.是其它栈中点,首先不会是在x与它之间点y,因为y会比x更早被判断弹出(low[y]=dfn[y]),关于y的其它情况同上同下,如果是在x底下,那"x无法回溯到在它之前且在栈中的点"这一条件就不成立了)。这一切都源于tarjan算法本质为dfs!
    在这里插入图片描述
  • 如果判断条件改为改成low[x]<low[v],更新改为low[x]=low[v],则上述证明中只有“low值为x”这一种情况。
  • tarjan算法
void tarjan(int x)
{
	dfn[x]=low[x]=++dindex;
	instack[x]=true;
	stap[++stop]=x;
	for(int i=last[x];i;i=e[i].next)
	{
		int v=e[i].v;
		if(!dfn[v])
		{
			tarjan(v);
			low[x]=min(low[x],low[v]);
		}
		else if(instack[v]&&low[x]>dfn[v])//经测试low[x]>low[v]也可,对应上述多次连接的情况
		low[x]=dfn[v];
	}
	int j;
	if(dfn[x]==low[x])
	{
		bcnt++;//缩点后的点编号
		do{
			 j=stap[stop--];
			belong[j]=bcnt;
			instack[j]=false;
			powe[bcnt]+=dian[j];//权值和
		}
		while(j!=x);
	}
}
  • 将缩点完成后的DAG图练成一个强连通图:假设入度为零的点数为a,出度为零的点数为b,所需要的最小边数为max(a,b);若原图已经强连通,所需要的边数为0.
  • tarjan给出了反拓扑序,不需要再额外topsort。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈希表扁豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值