强连通分量与双连通分量 复习笔记
前言#
改 Atcoder 的时候遇到了双连通分量,然后想起来这东西我两个月之前学得很不好,所以再来看一下啊。
强连通分量#
强连通的定义是:有向图
强连通分量(
然后就是如何求出一张有向图当中的强连通分量。用
其中:
那么我们考虑如何维护这两个值。
il void Tarjan(int u)
dfn[u]=++idx;
并且,此时
dfn[u]=low[u]=++idx;
同时我们将
s.push(u),in_stack[u]=1;
然后我们从
如果
if(!dfn[v]){
Tarjan(v,u);
low[u]=min(low[u],low[v]);
}
否则,如果
else if(in_stack[v])low[u]=min(low[u],dfn[v]);
如果以上两种情况都不是,也就是说
以上,就是对相邻结点的访问过程。接下来我们要进行一个判断:
if(low[u]==dfn[u])
如果成立,就说明
解释就是,反证一下,假如此条件成立,但
所以如果此条件成立,就说明
if(low[u]==dfn[u]){
int j;
cnt_scc++;
do{
j=s.top();
s.pop();
in_stk[j]=0;
scc[j]=cnt_scc;
}while(j!=u);
}
然后就结束了啊!(附上完整的
#define il inline
#define re register
il void Tarjan(int u){
dfn[u]=low[u]=++idx;
s.push(u),in_stack[u]=1;
for(re int i=head[u];i;i=e[i].nxt){
int v=e[i].v;
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(in_stack[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
int j;
cnt_scc++;
do{
j=s.top();
s.pop();
in_stk[j]=0;
scc[j]=cnt_scc;
}while(j!=u);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人