Tarjan算法(发现强连通图的算法)
Tarjan算法也是用来发现强连通子图的算法,是Kosaraju算法的改进,算法复杂度是,算法比较简单,位代码和java实现代码如下:
package cn.edu.dlut.wisdom;
import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.objects.*;
import it.unimi.dsi.webgraph.*;
import java.util.Comparator;
/**
** @author You Wang* Input: Graph G = (V, E)* index = 0 // DFS node number counter* S = empty // An empty stack of nodes* forall v in V do* if (v.index is undefined) // Start a DFS at each node* tarjan(v) // we haven't visited yet** procedure tarjan(v)* v.index = index // Set the depth index for v* v.lowlink = index* index = index + 1* S.push(v) // Push v on the stack* forall (v, v') in E do // Consider successors of v* if (v'.index is undefined) // Was successor v' visited?* tarjan(v') // Recurse* v.lowlink = min(v.lowlink, v'.lowlink)* else if (v' is in S) // Was successor v' in stack S?* v.lowlink = min(v.lowlink, v'.index )* if (v.lowlink == v.index) // Is v the root of an SCC?* print "SCC:"* repeat* v' = S.pop* print v'* until (v' == v)*/public class Tarjan {private ImmutableGraph graph;
private ObjectAVLTreeSet<IntAVLTreeSet> sccs;
private int[] indexs;private int[] lowLinks;private int numNodes;private IntArrayList stack;
private int index;public Tarjan(ImmutableGraph graph) {
this.graph = graph;
numNodes = graph.numNodes();}public void tarjan(int v) {indexs[v] = index;lowLinks[v] = index;index++;stack.push(v);for(int successor : graph.successorArray(v)) {if(indexs[successor] == -1) {
tarjan(successor);lowLinks[v] = Math.min(lowLinks[v], lowLinks[successor]);}else if(stack.contains(successor))lowLinks[v] = Math.min(lowLinks[v], indexs[successor]);}if (lowLinks[v] == indexs[v]) {
int n;
IntAVLTreeSet component = new IntAVLTreeSet();
do {
n = stack.popInt();component.add(n);} while(n != v);
sccs.add(component);}}public ObjectAVLTreeSet<IntAVLTreeSet> compute() {
Comparator cmp = new Comparator() {
public int compare(Object o1, Object o2) {if(o1 instanceof IntAVLTreeSet && o2 instanceof IntAVLTreeSet) {IntAVLTreeSet s1 = (IntAVLTreeSet)o1;IntAVLTreeSet s2 = (IntAVLTreeSet)o2;if (s1.size() != s2.size())
return s1.size() - s2.size();
else
{int[] a1 = s1.toIntArray();
int[] a2 = s2.toIntArray();
for (int i = 0; i < a1.length; i++)if (a1[i] != a2[i])
return a1[i] - a2[i];
return 0;
}}else
throw new IllegalArgumentException("The argument must be an IntAVLTreeSet");}};sccs = new ObjectAVLTreeSet<IntAVLTreeSet>(cmp);
indexs = new int[numNodes];for(int i = 0; i < numNodes; i++)indexs[i] = -1;lowLinks = new int[numNodes];stack = new IntArrayList();
index = 0;for(int i = 0; i < numNodes; i++)if(indexs[i] == -1)
tarjan(i);return sccs;
}}

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名小橋流水(包含链接)。如您有任何疑问或者授权方面的协商,请给我发邮件。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述