强连通分量
定义:
强连通指的是对于一个有向图,每个点都有路径到另外一个点。
强连通分量则指的是对于一个图,它的极大强连通子图。
tanjan 求法:
对于一个图,考虑他的 dfs 生成树(即为对原图进行 dfs 的一棵树)。
那么对于这棵树,搜索时会出现四种边:
树枝边:搜索到没被访问过的节点,且在树中是当前节点的直接儿子。
前向边:搜索到没被访问的节点,但在树中是当前节点的间接儿子。
横叉边:搜索到已访问到的节点,但不是当前节点的祖先。
返祖边:搜索到已访问的节点,且是当前节点的祖先。
性质: 如果
证明: 反证法即可。
那么现在我们考虑到达
在回溯的过程中,维护一个栈,用于存储待处理的节点。
再考虑在以
那么对于没被访问的节点,有
对于访问过的且在栈中的节点,有
其他情况对
那么当
且因为以
代码:
void tarjan(int u){ dfn[u]=low[u]=++dfnnow; vis[u]=true; st[++top]=u; in_st[u]=true; for(int i=head[u];i;i=edges[i].next){ int v=edges[i].v; if(!vis[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if(in_st[v]){ low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ scc++; while(st[top]!=u){ siz[scc]++; in_st[st[top]]=false; col[st[top]]=scc; top--; } siz[scc]++; in_st[st[top]]=false; col[st[top]]=scc; top--; } return; }
本文作者:Little_corn
本文链接:https://www.cnblogs.com/little-corn/p/18157430
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步