20251222强连通分量总结

强连通分量

一张有向图,如果该图任意两点之间连通,则称该图强连通。

有向图的子图中的任意点相互连通叫做强连通子图,而如果该子图不能再大了也就是已达到最大,那么该子图叫做极大强连通子图,也就是强连通分量。
1
2
3
4
5
6
7

那么该图有三个强连通分量,分别是{1,2,3}、{4,5,6}、{7}。

实现

cpp 复制代码
void dfs(int x){
	dfn[x]=low[x]=++cnt;//dfn序
	s.push(x);//推入栈
	for(int i=0;i<E[x].size();i++){
		int v=E[x][i];
		if(dfn[v]==0){//如果没来过
			dfs(v);
			low[x]=min(low[x],low[v]);//更新
		}else if(gp[v]==0){//不然看他有没有被分过组
			low[x]=min(low[x],dfn[v]);//更新
		}
	}
	if(low[x]==dfn[x]){//如果他没被其他点更新过
		gp[x]=++id;//分组
		while(s.top()!=x){//如果栈顶不是x
			gp[s.top()]=id;
			s.pop();
		}
		s.pop();
	}
}

缩点

就是找到强连通分量后将整个强连通分量缩成一个点,按上图作样例。
1* 1,2,3
2* 4,5,6
3* 7

打星号的是强连通分量的编号。

实现

cpp 复制代码
for(int i=1;i<=n;i++){
	for(int j=0;j<E[i].size();j++){
		int v=E[i][j];
		if(gp[i]!=gp[v]){//如果两点属于的组不一样
			e[gp[i]].push_back(gp[v]);//新图连边
		}
	}
}

边双连通分量

把强连通分量中的有向边替换成无向边,就是一个边双连通分量,所以求边双连通分量更求强连通分量差不多,只需多判一个重边就行了。

cpp 复制代码
void dfs(int x,int fa){
	dfn[x]=low[x]=++cnt;
	s.push(x);
	bool cc=0;
	for(int i=0;i<E[x].size();i++){
		int v=E[x][i];
		if(v==fa){//发现跑了回来
		    if(!cc){//如果还没出现过
		        cc=1;
		    }else{
		        low[x]=min(low[x],dfn[v]);//否则更新
		    }
		    continue;
		}
		if(dfn[v]==0){
			dfs(v,x);
			low[x]=min(low[x],low[v]);
		}else if(gp[v]==0){
			low[x]=min(low[x],dfn[v]);
		}
	}
	if(low[x]==dfn[x]){
		gp[x]=++id;
		while(s.top()!=x){
			gp[s.top()]=id;
			s.pop();
		}
		s.pop();
	}
}
相关推荐
Jasmine_llq2 个月前
《P2656 采蘑菇》
算法·强连通分量·广度优先搜索(bfs)·tarjan 算法·图的缩点操作·有向无环图(dag)·最长路径
XuYueming5 个月前
圆方树学习笔记 —— 一种关于点双连通分量的思考方式
题解·lca·缩点·tarjan·圆方树·点双连通分量·树链剖分·记录 & 心得·仙人掌·理论 / 算法·bzoj·hydro·图的连通性·动态 dp / ddp
闻缺陷则喜何志丹7 个月前
【强连通分量 拓扑序】P9431 [NAPC-#1] Stage3 - Jump Refreshers|普及+
c++·算法·图论·拓扑序·洛谷·强连通分量
闻缺陷则喜何志丹7 个月前
【强连通分量 缩点 拓扑排序】P3387 【模板】缩点|普及+
c++·算法·拓扑排序·洛谷·强连通分量·缩点
Qres8212 年前
缩点+图论路径网络流:1114T4
图论·网络流·缩点
陈进士学习2 年前
1513:受欢迎的牛(DFS&tarjan&强连通分量)
c语言·数据结构·算法·深度优先·图论·强连通分量