图论-强连通分量
这是一份 Tarjan 求强连通分量的板子
其中和求割点,割边相同:
dfn[ ]
表示为时间戳数组
back[ ]
表示为能访问到的最远祖先(如果该祖先暂无SCC)
针对求解强联通分量,需要多定义如下变量
stack<int> st;
用于存放 dfs 中的路径,从栈顶一直到 这个点本身(指 dfs 中 u)的点就是一个sccint sccno[ ];
表示这个点属于第几个 scc
点击查看代码
int head[N], cnt;
struct Edge{
int from, to, nxt;
}e[N << 1];
void add(int u, int v){
e[++cnt].from = u;
e[cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
}
int ans_scc, sccno[N], dfn[N], back[N], tim;
stack<int> st;
void dfs(int u){
st.push(u);
dfn[u] = back[u] = ++tim;
for(int i = head[u]; i != 0; i = e[i].nxt){
int v = e[i].to;
if(!dfn[v]){
dfs(v);
back[u] = min(back[u], back[v]);
}else if(!sccno[v]){
back[u] = min(back[u], dfn[v]);
// back[u] = min(back[u], back[v]);
}
}
if(back[u] == dfn[u]){
ans_scc++;
while(1){
int v = st.top();
st.pop();
sccno[v] = ans_scc;
if(u == v) break;
}
}
}
void Tarjan(int n){
ans_scc = tim = 0;
memset(sccno, 0, sizeof(sccno));
memset(dfn, 0, sizeof(dfn));
memset(back, 0, sizeof(back));
for(int i = 1; i <= n; i++){
if(!dfn[i])
dfs(i);
}
}
其中代码为
else if(!sccno[v]){
back[u] = min(back[u], dfn[v]);
// back[u] = min(back[u], back[v]); 这个也可以,与割点不同
}
有以下几点注意点:有以下几点注意点:
1. 在有向图中,back[i] 数组的意义更新了,现在一个点可以通过其祖先节点访问到更祖先的节点,结果显然成立,因为是有向图,并且求解问题不同。于是back[u] = min(back[u], back[v]);
成立
2.笔者归结 Tarjan 的简化理解步骤2.笔者归结 Tarjan 的简化理解步骤
- 所有节点都想往上爬(将自己的能力提升),规定所有节点的能力只能依靠自己和子节点的能力,而不能依靠祖先节点的能力,证明也很显然,如果自己和儿子都不争气,不能连接到更先的父节点,那就只能自己成为一个 scc 了
- 当 dfs 到了节点 u 时,此时 u 为根节点,拓展下去一颗“树”,首先,大家起始的能力就是自己,当然“辈分越大,能力也越大”,当 dfs 到了节点 u 时,此时 u 为根节点,拓展下去一颗“树”,首先,大家起始的能力就是自己,当然“辈分越大,能力也越大”
于是,事情就变成了,所有节点都在期待一个突然爆发的子节点(或者靠本身),能使它本身连接到一个 dfn 最小的祖先节点。然后,针对节点 u ,
如果它与它子节点的努力得到了回报(指 back[u] < dfn[u]),那么递归返回到 u 时,就不用在 u 处更新一个新的 scc ,而在 u 的祖先节点处更新一个更大的 scc ;
如果(back[u] == dfn[u]),说明这个分支到此为止了,所有存在 stack 里的点都是这个 scc 的一员
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)