Tarjan Algorithm

Find Strongly Connected Components

Posted by bboyhao on July 18, 2019

Overview

Tarjan algorithm is used to find SCCs in a directed graph. Compared to Korasaju’s algorithm, it only DFS once and no need to transpose the graph. It has linear time complexity of O(|V|+|E|).

Implementation using Go

package main

import (
	"fmt"
	"tarjan/graph"
)

var timeStamp int = 1
var stack = make([]*Node, 0)

type Node = graph.Node

func main() {
	n1 := Node{Id: 1, Neighbours: make([]*Node, 0)}
	n2 := Node{Id: 2, Neighbours: make([]*Node, 0)}
	n3 := Node{Id: 3, Neighbours: make([]*Node, 0)}
	n4 := Node{Id: 4, Neighbours: make([]*Node, 0)}
	n5 := Node{Id: 5, Neighbours: make([]*Node, 0)}
	n6 := Node{Id: 6, Neighbours: make([]*Node, 0)}
	n1.AddNeighbour(&n2)
	n2.AddNeighbour(&n3)
	n3.AddNeighbour(&n4)
	n4.AddNeighbour(&n5)
	n5.AddNeighbour(&n6)
	n6.AddNeighbour(&n1)

	tarjan(&n1)
}

func tarjan(u *Node) {
	u.Visited = true
	u.Low = timeStamp
	u.Dfn = timeStamp
	timeStamp += 1
	stack = append(stack, u)
	for _, v := range u.Neighbours {
		if v.Dfn == 0 {
			tarjan(v)
			u.Low = min(v.Low, u.Low)
		} else {
			u.Low = min(v.Dfn, u.Low)
		}
	}
	if u.Low == u.Dfn {
		for stack[len(stack)-1].Id != u.Id {
			last := stack[len(stack)-1]
			stack = stack[:len(stack)-1]
			last.Visited = false
			fmt.Println(last.Id)
		}
		last := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		last.Visited = false
		fmt.Println(last.Id)
		fmt.Println()
	}
}

func min(a int, b int) int {
	if a >= b {
		return b
	}
	return a
}
package graph

type Node struct {
	Id         int
	Visited    bool
	Low        int
	Dfn        int
	Neighbours []*Node
}

func (u *Node) AddNeighbour(v *Node) {
	u.Neighbours = append(u.Neighbours, v)
}

Details about this algorithm

More details can be found at this link