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;}}elsethrow 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 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名小橋流水(包含链接)。如您有任何疑问或者授权方面的协商,请给我发邮件。
浙公网安备 33010602011771号