Kosaraju

From Rosetta Code
Task
Kosaraju
You are encouraged to solve this task according to the task description, using any language you may know.
This page uses content from Wikipedia. The original article was at Graph. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)


Kosaraju's algorithm (also known as the Kosaraju–Sharir algorithm) is a linear time algorithm to find the strongly connected components of a directed graph. Aho, Hopcroft and Ullman credit it to an unpublished paper from 1978 by S. Rao Kosaraju. The same algorithm was independently discovered by Micha Sharir and published by him in 1981. It makes use of the fact that the transpose graph (the same graph with the direction of every edge reversed) has exactly the same strongly connected components as the original graph.

References

11l

Translation of: Python

<lang 11l>F kosaraju(g)

  V size = g.len
  V vis = [0B] * size
  V l = [0] * size
  V x = size
  V t = [[Int]()] * size
  F visit(Int u) -> N
     I !@vis[u]
        @vis[u] = 1B
        L(v) @g[u]
           @visit(v)
           @t[v] [+]= u
        @x--
        @l[@x] = u
  L(u) 0 .< g.len
     visit(u)
  V c = [0] * size
  F assign(Int u, root) -> N
     I @vis[u]
        @vis[u] = 0B
        @c[u] = root
        L(v) @t[u]
           @assign(v, root)
  L(u) l
     assign(u, u)
  R c

V g = [[1], [2], [0], [1, 2, 4], [3, 5], [2, 6], [5], [4, 6, 7]] print(kosaraju(g))</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

C#

<lang csharp>using System; using System.Collections.Generic;

class Node { public enum Colors { Black, White, Gray }

public Colors color { get; set; } public int N { get; }

public Node(int n) { N = n; color = Colors.White; } }

class Graph { public HashSet<Node> V { get; } public Dictionary<Node, HashSet<Node>> Adj { get; }

/// <summary> /// Kosaraju's strongly connected components algorithm /// </summary> public void Kosaraju() { var L = new HashSet<Node>();

Action<Node> Visit = null; Visit = (u) => { if (u.color == Node.Colors.White) { u.color = Node.Colors.Gray;

foreach (var v in Adj[u]) Visit(v);

L.Add(u); } };

Action<Node, Node> Assign = null; Assign = (u, root) => { if (u.color != Node.Colors.Black) { if (u == root) Console.Write("SCC: ");

Console.Write(u.N + " "); u.color = Node.Colors.Black;

foreach (var v in Adj[u]) Assign(v, root);

if (u == root) Console.WriteLine(); } };

foreach (var u in V) Visit(u);

foreach (var u in L) Assign(u, u); } }</lang>

C++

Translation of: D

<lang cpp>#include <functional>

  1. include <iostream>
  2. include <ostream>
  3. include <vector>

template<typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {

   auto it = v.cbegin();
   auto end = v.cend();
   os << "[";
   if (it != end) {
       os << *it;
       it = std::next(it);
   }
   while (it != end) {
       os << ", " << *it;
       it = std::next(it);
   }
   return os << "]";

}

std::vector<int> kosaraju(std::vector<std::vector<int>>& g) {

   // 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
   auto size = g.size();
   std::vector<bool> vis(size);           // all false by default
   std::vector<int> l(size);              // all zero by default
   auto x = size;                         // index for filling l in reverse order
   std::vector<std::vector<int>> t(size); // transpose graph
   // Recursive subroutine 'visit':
   std::function<void(int)> visit;
   visit = [&](int u) {
       if (!vis[u]) {
           vis[u] = true;
           for (auto v : g[u]) {
               visit(v);
               t[v].push_back(u); // construct transpose
           }
           l[--x] = u;
       }
   };
   // 2. For each vertex u of the graph do visit(u)
   for (int i = 0; i < g.size(); ++i) {
       visit(i);
   }
   std::vector<int> c(size); // used for component assignment
   // Recursive subroutine 'assign':
   std::function<void(int, int)> assign;
   assign = [&](int u, int root) {
       if (vis[u]) { // repurpose vis to mean 'unassigned'
           vis[u] = false;
           c[u] = root;
           for (auto v : t[u]) {
               assign(v, root);
           }
       }
   };
   // 3: For each element u of l in order, do assign(u, u)
   for (auto u : l) {
       assign(u, u);
   }
   return c;

}

std::vector<std::vector<int>> g = {

   {1},
   {2},
   {0},
   {1, 2, 4},
   {3, 5},
   {2, 6},
   {5},
   {4, 6, 7},

};

int main() {

   using namespace std;
   cout << kosaraju(g) << endl;
   return 0;

}</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

D

Translation of: Kotlin

(mostly) with output like

Translation of: Go

<lang D>import std.container.array; import std.stdio;

/* the list index is the first vertex in the edge(s) */ auto g = [

   [1],
   [2],
   [0],
   [1, 2, 4],
   [3, 5],
   [2, 6],
   [5],
   [4, 6, 7],

];

int[] kosaraju(int[][] g) {

   // 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
   auto size = g.length; // all false by default
   Array!bool vis;
   vis.length = size;
   int[] l;              // all zero by default
   l.length = size;
   auto x = size;        // index for filling l in reverse order
   int[][] t;            // transpose graph
   t.length = size;
   // Recursive subroutine 'visit':
   void visit(int u) {
       if (!vis[u]) {
           vis[u] = true;
           foreach (v; g[u]) {
               visit(v);
               t[v] ~= u;  // construct transpose
           }
           l[--x] = u;
       }
    }
   // 2. For each vertex u of the graph do visit(u)
   foreach (u, _; g) {
       visit(u);
   }
   int[] c;  // used for component assignment
   c.length = size;
   // Recursive subroutine 'assign':
   void assign(int u, int root) {
       if (vis[u]) {  // repurpose vis to mean 'unassigned'
           vis[u] = false;
           c[u] = root;
           foreach(v; t[u]) {
               assign(v, root);
           }
       }
   }
   // 3: For each element u of l in order, do assign(u, u)
   foreach (u; l) {
       assign(u, u);
   }
   return c;

}

void main() {

   writeln(kosaraju(g));

}</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

Go

<lang go>package main

import "fmt"

var g = [][]int{

   0: {1},
   1: {2},
   2: {0},
   3: {1, 2, 4},
   4: {3, 5},
   5: {2, 6},
   6: {5},
   7: {4, 6, 7},

}

func main() {

   fmt.Println(kosaraju(g))

}

func kosaraju(g [][]int) []int {

   // 1. For each vertex u of the graph, mark u as unvisited. Let L be empty.
   vis := make([]bool, len(g))
   L := make([]int, len(g))
   x := len(L)                // index for filling L in reverse order
   t := make([][]int, len(g)) // transpose graph
   // 2. recursive subroutine:
   var Visit func(int)
   Visit = func(u int) {
       if !vis[u] {
           vis[u] = true
           for _, v := range g[u] {
               Visit(v)
               t[v] = append(t[v], u) // construct transpose
           }
           x--
           L[x] = u
       }
   }
   // 2. For each vertex u of the graph do Visit(u)
   for u := range g {
       Visit(u)
   }
   c := make([]int, len(g)) // result, the component assignment
   // 3: recursive subroutine:
   var Assign func(int, int)
   Assign = func(u, root int) {
       if vis[u] { // repurpose vis to mean "unassigned"
           vis[u] = false
           c[u] = root
           for _, v := range t[u] {
               Assign(v, root)
           }
       }
   }
   // 3: For each element u of L in order, do Assign(u,u)
   for _, u := range L {
       Assign(u, u)
   }
   return c

}</lang>

Output:
[0 0 0 3 3 5 5 7]

Java

Translation of: Kotlin

Output is like Go instead of what Kotlin outputs. <lang java>import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiConsumer; import java.util.function.IntConsumer; import java.util.stream.Collectors;

public class Kosaraju {

   static class Recursive {
       I func;
   }
   private static List<Integer> kosaraju(List<List<Integer>> g) {
       // 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
       int size = g.size();
       boolean[] vis = new boolean[size];
       int[] l = new int[size];
       AtomicInteger x = new AtomicInteger(size);
       List<List<Integer>> t = new ArrayList<>();
       for (int i = 0; i < size; ++i) {
           t.add(new ArrayList<>());
       }
       Recursive<IntConsumer> visit = new Recursive<>();
       visit.func = (int u) -> {
           if (!vis[u]) {
               vis[u] = true;
               for (Integer v : g.get(u)) {
                   visit.func.accept(v);
                   t.get(v).add(u);
               }
               int xval = x.decrementAndGet();
               l[xval] = u;
           }
       };
       // 2. For each vertex u of the graph do visit(u)
       for (int i = 0; i < size; ++i) {
           visit.func.accept(i);
       }
       int[] c = new int[size];
       Recursive<BiConsumer<Integer, Integer>> assign = new Recursive<>();
       assign.func = (Integer u, Integer root) -> {
           if (vis[u]) {  // repurpose vis to mean 'unassigned'
               vis[u] = false;
               c[u] = root;
               for (Integer v : t.get(u)) {
                   assign.func.accept(v, root);
               }
           }
       };
       // 3: For each element u of l in order, do assign(u, u)
       for (int u : l) {
           assign.func.accept(u, u);
       }
       return Arrays.stream(c).boxed().collect(Collectors.toList());
   }
   public static void main(String[] args) {
       List<List<Integer>> g = new ArrayList<>();
       for (int i = 0; i < 8; ++i) {
           g.add(new ArrayList<>());
       }
       g.get(0).add(1);
       g.get(1).add(2);
       g.get(2).add(0);
       g.get(3).add(1);
       g.get(3).add(2);
       g.get(3).add(4);
       g.get(4).add(3);
       g.get(4).add(5);
       g.get(5).add(2);
       g.get(5).add(6);
       g.get(6).add(5);
       g.get(7).add(4);
       g.get(7).add(6);
       g.get(7).add(7);
       List<Integer> output = kosaraju(g);
       System.out.println(output);
   }

}</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

Julia

Works with: Julia version 0.6
Translation of: Go

<lang julia>function korasaju(g::Vector{Vector{T}}) where T<:Integer

   # 1. For each vertex u of the graph, mark u as unvisited. Let L be empty.
   vis = falses(length(g))
   L   = Vector{T}(length(g))
   x   = length(L) + 1
   t   = collect(T[] for _ in eachindex(g))
   # Recursive
   function visit(u::T)
       if !vis[u]
           vis[u] = true
           for v in g[u]
               visit(v)
               push!(t[v], u)
           end
           x -= 1
           L[x] = u
       end
   end
   # 2. For each vertex u of the graph do visit(u)
   for u in eachindex(g)
       visit(u)
   end
   c = Vector{T}(length(g))
   # 3. Recursive subroutine:
   function assign(u::T, root::T)
       if vis[u]
           vis[u] = false
           c[u] = root
           for v in t[u]
               assign(v, root)
           end
       end
   end
   # 3. For each element u of L in order, do assign(u, u)
   for u in L
       assign(u, u)
   end
   return c

end

g = [[2], [3], [1], [2, 3, 5], [4, 6], [3, 7], [6], [5, 7, 8]] println(korasaju(g))</lang>

Output:
[1, 1, 1, 4, 4, 6, 6, 8]

Kotlin

Translation of: Go

<lang scala>// version 1.1.3

/* the list index is the first vertex in the edge(s) */ val g = listOf(

   intArrayOf(1),        // 0
   intArrayOf(2),        // 1
   intArrayOf(0),        // 2
   intArrayOf(1, 2, 4),  // 3
   intArrayOf(3, 5),     // 4
   intArrayOf(2, 6),     // 5
   intArrayOf(5),        // 6
   intArrayOf(4, 6, 7)   // 7

)

fun kosaraju(g: List<IntArray>): List<List<Int>> {

   // 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
   val size = g.size
   val vis = BooleanArray(size)                 // all false by default
   val l = IntArray(size)                       // all zero by default
   var x = size                                 // index for filling l in reverse order
   val t = List(size) { mutableListOf<Int>() }  // transpose graph
   
   // Recursive subroutine 'visit':
   fun visit(u: Int) {
       if (!vis[u]) {
           vis[u] = true
           for (v in g[u]) { 
               visit(v)
               t[v].add(u)  // construct transpose 
           }
           l[--x] = u
       }
    }
   // 2. For each vertex u of the graph do visit(u)
   for (u in g.indices) visit(u)
   val c = IntArray(size)  // used for component assignment 
   // Recursive subroutine 'assign':
   fun assign(u: Int, root: Int) {
       if (vis[u]) {  // repurpose vis to mean 'unassigned'
           vis[u] = false
           c[u] = root
           for (v in t[u]) assign(v, root)
       }
   }
   // 3: For each element u of l in order, do assign(u, u)
   for (u in l) assign(u, u)
   // Obtain list of SCC's from 'c' and return it   
   return c.withIndex()
           .groupBy { it.value }.values
           .map { ivl -> ivl.map { it.index } }

}

fun main(args: Array<String>) {

   println(kosaraju(g).joinToString("\n"))

}</lang>

Output:
[0, 1, 2]
[3, 4]
[5, 6]
[7]

Lua

Translation of: C++

<lang lua>function write_array(a)

   io.write("[")
   for i=0,#a do
       if i>0 then
           io.write(", ")
       end
       io.write(tostring(a[i]))
   end
   io.write("]")

end

function kosaraju(g)

   -- 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
   local size = #g
   local vis = {}
   for i=0,size do
       -- all false by default
       vis[i] = false
   end
   local l = {}
   for i=0,size do
       -- all zero by default
       l[i] = 0
   end
   local x = size+1  -- index for filling l in reverse order
   local t = {}    -- transpose graph
   -- Recursive subroutine 'visit'
   function visit(u)
       if not vis[u] then
           vis[u] = true
           for i=0,#g[u] do
               local v = g[u][i]
               visit(v)
               if t[v] then
                   local a = t[v]
                   a[#a+1] = u
               else
                   t[v] = {[0]=u}
               end
           end
           x = x - 1
           l[x] = u
       end
   end
   -- 2. For each vertex u of the graph do visit(u)
   for i=0,#g do
       visit(i)
   end
   local c = {}
   for i=0,size do
       -- used for component assignment
       c[i] = 0
   end
   -- Recursive subroutine 'assign'
   function assign(u, root)
       if vis[u] then  -- repurpose vis to mean 'unassigned'
           vis[u] = false
           c[u] = root
           for i=0,#t[u] do
               local v = t[u][i]
               assign(v, root)
           end
       end
   end
   -- 3: For each element u of l in order, do assign(u, u)
   for i=0,#l do
       local u = l[i]
       assign(u, u)
   end
   return c

end

-- main local g = {

   [0]={[0]=1},
   [1]={[0]=2},
   [2]={[0]=0},
   [3]={[0]=1, [1]=2, [2]=4},
   [4]={[0]=3, [1]=5},
   [5]={[0]=2, [1]=6},
   [6]={[0]=5},
   [7]={[0]=4, [1]=6, [2]=7},

}

write_array(kosaraju(g)) print()</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

Nim

Translation of: Kotlin

<lang Nim>type

 Vertex = int
 Graph = seq[seq[Vertex]]
 Scc = seq[Vertex]

func korasaju(g: Graph): seq[Scc] =

 var
   size = g.len
   visited = newSeq[bool](size)        # All false by default.
   l = newSeq[Vertex](size)            # All zero by default.
   x = size                            # Index for filling "l" in reverse order.
   t = newSeq[seq[Vertex]](size)       # Transposed graph.
   c = newSeq[Vertex](size)            # Used for component assignment.
 func visit(u: Vertex) =
   if not visited[u]:
     visited[u] = true
     for v in g[u]:
       visit(v)
       t[v].add(u)   # Construct transposed graph.
     dec x
     l[x] = u
 func assign(u, root: Vertex) =
   if visited[u]:
     # Repurpose visited to mean 'unassigned'.
     visited[u] = false
     c[u] = root
     for v in t[u]: v.assign(root)
 for u in 0..g.high: u.visit()
 for u in l: u.assign(u)
 # Build list of strongly connected components.
 var prev = -1
 for v1, v2 in c:
   if v2 != prev:
     prev = v2
     result.add @[]
   result[^1].add v1


when isMainModule:

 let g = @[@[1], @[2], @[0], @[1, 2, 4], @[3, 5], @[2, 6], @[5], @[4, 6, 7]]
 for scc in korasaju(g): echo $scc</lang>
Output:
@[0, 1, 2]
@[3, 4]
@[5, 6]
@[7]

Perl

Translation of: Raku

<lang perl>use strict; use warnings; use feature 'say';

sub kosaraju {

   our(%k) = @_;
   our %g = ();
   our %h;
   my $i = 0;
   $g{$_}     = $i++ for sort keys %k;
   $h{$g{$_}} = $_   for      keys %g; # invert
   our(%visited, @stack, @transpose, @connected);
   sub visit {
       my($u) = @_;
       unless ($visited{$u}) {
           $visited{$u} = 1;
           for my $v (@{$k{$u}}) {
               visit($v);
               push @{$transpose[$g{$v}]}, $u;
           }
           push @stack, $u;
       }
   }
   sub assign {
       my($u, $root) = @_;
       if ($visited{$u}) {
           $visited{$u} = 0;
           $connected[$g{$u}] = $root;
           assign($_, $root) for @{$transpose[$g{$u}]};
       }
   }
   visit($_) for sort keys %g;
   assign($_, $_) for reverse @stack;
   my %groups;
   for my $i (0..$#connected) {
       my $id = $g{$connected[$i]};
       push @{$groups{$id}}, $h{$i};
   }
   say join ' ', @{$groups{$_}} for sort keys %groups;

}

my %test1 = (

   0 => [1],
   1 => [2],
   2 => [0],
   3 => [1, 2, 4],
   4 => [3, 5],
   5 => [2, 6],
   6 => [5],
   7 => [4, 6, 7]

);

my %test2 = (

  'Andy' => ['Bart'],
  'Bart' => ['Carl'],
  'Carl' => ['Andy'],
  'Dave' => [<Bart Carl Earl>],
  'Earl' => [<Dave Fred>],
  'Fred' => [<Carl Gary>],
  'Gary' => ['Fred'],
  'Hank' => [<Earl Gary Hank>]

);

kosaraju(%test1); say ; kosaraju(%test2);</lang>

Output:
0 1 2
3 4
5 6
7

Andy Bart Carl
Dave Earl
Fred Gary
Hank

Phix

<lang Phix>sequence visited, l, t, c

procedure visit(sequence g, integer u)

   if not visited[u] then
       visited[u] = true
       for i=1 to length(g[u]) do
           integer v = g[u][i]
           visit(g,v)
           t[v] &= u
       end for
       l &= u
   end if

end procedure

procedure assign(integer u, root=u)

   if visited[u] then
       visited[u] = false
       c[u] = root
       for v=1 to length(t[u]) do
           assign(t[u][v], root)
       end for
   end if

end procedure

function korasaju(sequence g)

   integer len = length(g)
   visited = repeat(false,len)
   l = {}
   t = repeat({},len)
   for u=1 to len do
       visit(g,u)
   end for
   c = repeat(0,len)
   for u=length(l) to 1 by -1 do
       assign(l[u])
   end for
   return c

end function

constant g = {{2}, {3}, {1}, {2, 3, 5}, {4, 6}, {3, 7}, {6}, {5, 7, 8}} ?korasaju(g)</lang>

Output:
{1,1,1,4,4,6,6,8}

Python

<lang python>def kosaraju(g):

   class nonlocal: pass
   # 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
   size = len(g)
   vis = [False]*size # vertexes that have been visited
   l = [0]*size
   nonlocal.x = size
   t = [[]]*size   # transpose graph
   def visit(u):
       if not vis[u]:
           vis[u] = True
           for v in g[u]:
               visit(v)
               t[v] = t[v] + [u]
           nonlocal.x = nonlocal.x - 1
           l[nonlocal.x] = u
   # 2. For each vertex u of the graph do visit(u)
   for u in range(len(g)):
       visit(u)
   c = [0]*size
   def assign(u, root):
       if vis[u]:
           vis[u] = False
           c[u] = root
           for v in t[u]:
               assign(v, root)
   # 3: For each element u of l in order, do assign(u, u)
   for u in l:
       assign(u, u)
   return c

g = [[1], [2], [0], [1,2,4], [3,5], [2,6], [5], [4,6,7]] print kosaraju(g)</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

Racket

<lang racket>#lang racket

(require racket/dict)

G is a dictionary of vertex -> (list vertex)

(define (Kosuraju G)

 (letrec
     ((vertices (remove-duplicates (append (dict-keys G) (append* (dict-values G)))))
      (visited?-dict (make-hash)) ; or any mutable dict type
      (assigned-dict (make-hash)) ; or any mutable dict type
      (neighbours:in (λ (u) (for/list (([v outs] (in-dict G)) #:when (member u outs)) v)))  
      (visit! (λ (u L)
                (cond [(dict-ref visited?-dict u #f) L]
                      [else (dict-set! visited?-dict u #t)
                            (cons u (for/fold ((L L)) ((v (in-list (dict-ref G u)))) (visit! v L)))])))  
      (assign! (λ (u root)
                 (unless (dict-ref assigned-dict u #f)
                   (dict-set! assigned-dict u root)
                   (for ((v (in-list (neighbours:in u)))) (assign! v root)))))
      (L (for/fold ((l null)) ((u (in-dict-keys G))) (visit! u l))))
   
   (for ((u (in-list L))) (assign! u u))  
   (map (curry map car) (group-by cdr (dict->list assigned-dict) =))))

(module+ test

 (Kosuraju '((0 1)
             (2 0)
             (5 2 6)
             (6 5)
             (1 2)
             (3 1 2 4) ; equvalent to (3 . (1 2 4))
             (4 5 3)
             (7 4 7 6))))</lang>
Output:
'((7) (6 5) (4 3) (2 1 0))

Raku

(formerly Perl 6)

Works with: Rakudo version 2018.09

Inspired by Python & Kotlin entries.

Accepts a hash of lists/arrays holding the vertex (name => (neighbors)) pairs. No longer limited to continuous, positive, integer vertex names.

<lang perl6>sub kosaraju (%k) {

   my %g = %k.keys.sort Z=> flat ^%k;
   my %h = %g.invert;
   my %visited;
   my @stack;
   my @transpose;
   my @connected;

   sub visit ($u) {
       unless %visited{$u} {
           %visited{$u} = True;
           for |%k{$u} -> $v {
               visit($v);
               @transpose[%g{$v}].push: $u;
           }
           @stack.push: $u;
       }
   }

   sub assign ($u, $root) {
       if %visited{$u} {
           %visited{$u}   = False;
           @connected[%g{$u}] = $root;
           assign($_, $root) for |@transpose[%g{$u}];
       }
   }

   .&visit for %g.keys;
   assign($_, $_) for @stack.reverse;
   (|%g{@connected}).pairs.categorize( *.value, :as(*.key) ).values.map: { %h{|$_} };

}

  1. TESTING

-> $test { say "\nStrongly connected components: ", |kosaraju($test).sort } for

  1. Same test data as all other entries, converted to a hash of lists

(((1),(2),(0),(1,2,4),(3,5),(2,6),(5),(4,6,7)).pairs.hash),

  1. Same layout test data with named vertices instead of numbered.

(

%(:Andy<Bart>,
  :Bart<Carl>,
  :Carl<Andy>,
  :Dave<Bart Carl Earl>,
  :Earl<Dave Fred>,
  :Fred<Carl Gary>,
  :Gary<Fred>,
  :Hank<Earl Gary Hank>)

)</lang>

Output:
Strongly connected components: (0 1 2)(3 4)(5 6)(7)

Strongly connected components: (Andy Bart Carl)(Dave Earl)(Fred Gary)(Hank)

Sidef

Translation of: Julia

<lang ruby>func korasaju(Array g) {

   # 1. For each vertex u of the graph, mark u as unvisited. Let L be empty.
   var vis = g.len.of(false)
   var L   = []
   var x   = g.end
   var t   = g.len.of { [] }
   # Recursive
   func visit(u) {
       if (!vis[u]) {
           vis[u] = true
           g[u].each {|v|
               visit(v)
               t[v] << u
           }
           L[x--] = u
       }
   }
   # 2. For each vertex u of the graph do visit(u)
   g.range.each {|u|
       visit(u)
   }
   var c = []
   # 3. Recursive subroutine:
   func assign(u, root) {
       if (vis[u]) {
           vis[u] = false
           c[u] = root
           t[u].each {|v|
               assign(v, root)
           }
       }
   }
   # 3. For each element u of L in order, do assign(u, u)
   L.each {|u|
       assign(u, u)
   }
   return c

}

var g = [[1], [2], [0], [1, 2, 4], [3, 5], [2, 6], [5], [4, 6, 7]] say korasaju(g)</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

Standard ML

<lang sml>datatype 'a node = Node of 'a * bool ref * 'a node list ref * 'a node list ref

fun node x = Node (x, ref false, ref nil, ref nil) fun mark (Node (_, r, _, _)) = !r before r := true fun unmark (Node (_, r, _, _)) = !r before r := false

fun value (Node (x, _, _, _)) = x fun sources (Node (_, _, ref xs, _)) = xs fun targets (Node (_, _, _, ref ys)) = ys

fun connect (m, n) =

 let
   val Node (_, _, _, ns) = m
   val Node (_, _, ms, _) = n
 in
   ms := m :: !ms;
   ns := n :: !ns
 end

datatype 'a step = One of 'a | Many of 'a list

fun visit (ms, nil) = ms

 | visit (ms, One m :: ss) = visit (m :: ms, ss)
 | visit (ms, Many nil :: ss) = visit (ms, ss)
 | visit (ms, Many (n :: ns) :: ss) =
   if mark n then
     visit (ms, Many ns :: ss)
   else
     visit (ms, Many (targets n) :: One n :: Many ns :: ss)

fun assign (xs, nil) = xs

 | assign (xs, nil :: ss) = assign (xs, ss)
 | assign (xs, (n :: ns) :: ss) =
   if unmark n then
     assign (value n :: xs, sources n :: ns :: ss)
   else
     assign (xs, ns :: ss)

fun assigns (xs, nil) = xs

 | assigns (xs, n :: ns) =
   if unmark n then
     let
       val x = sources n :: nil
       val x = value n :: assign (nil, x)
     in
       assigns (x :: xs, ns)
     end
   else
     assigns (xs, ns)

fun kosaraju xs = assigns (nil, visit (nil, Many xs :: nil))

fun make (n, is, ijs) =

 let
   val xs = Vector.tabulate (n, node)
   fun item i = Vector.sub (xs, i)
   fun step (i, j) = connect (item i, item j)
   fun path (i :: j :: js) = (step (i, j); path (j :: js))
     | path _ = ()
 in
   map item is before app path ijs
 end

val is = 0 :: nil val ijs =

 [0, 1, 2, 0, 3, 4, 0, 5, 7] ::
 [0, 9, 10, 11, 12, 9, 11] ::
 [1, 12] ::
 [3, 5, 6, 7, 8, 6, 15] ::
 [5, 13, 14, 13, 15] ::
 [8, 15] ::
 [10, 13] ::
 nil

val ns = make (16, is, ijs) val xs = kosaraju ns</lang>

Output:
> xs;
val it = [[15], [13, 14], [9, 10, 11, 12], [6, 7, 8], [5], [0, 1, 2, 3, 4]]: int list list

Swift

Translation of: D

<lang swift>func kosaraju(graph: Int) -> [Int] {

 let size = graph.count
 var x = size
 var vis = [Bool](repeating: false, count: size)
 var l = [Int](repeating: 0, count: size)
 var c = [Int](repeating: 0, count: size)
 var t = Int(repeating: [], count: size)
 func visit(_ u: Int) {
   guard !vis[u] else {
     return
   }
   vis[u] = true
   for v in graph[u] {
     visit(v)
     t[v].append(u)
   }
   x -= 1
   l[x] = u
 }
 for u in 0..<graph.count {
   visit(u)
 }
 func assign(_ u: Int, root: Int) {
   guard vis[u] else {
     return
   }
   vis[u] = false
   c[u] = root
   for v in t[u] {
     assign(v, root: root)
   }
 }
 for u in l {
   assign(u, root: u)
 }
 return c

}

let graph = [

 [1],
 [2],
 [0],
 [1, 2, 4],
 [3, 5],
 [2, 6],
 [5],
 [4, 6, 7]

]

print(kosaraju(graph: graph))</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

Visual Basic .NET

Translation of: Java

<lang vbnet>Module Module1

   Function Kosaraju(g As List(Of List(Of Integer))) As List(Of Integer)
       Dim size = g.Count
       Dim vis(size - 1) As Boolean
       Dim l(size - 1) As Integer
       Dim x = size
       Dim t As New List(Of List(Of Integer))
       For i = 1 To size
           t.Add(New List(Of Integer))
       Next
       Dim visit As Action(Of Integer) = Sub(u As Integer)
                                             If Not vis(u) Then
                                                 vis(u) = True
                                                 For Each v In g(u)
                                                     visit(v)
                                                     t(v).Add(u)
                                                 Next
                                                 x -= 1
                                                 l(x) = u
                                             End If
                                         End Sub
       For i = 1 To size
           visit(i - 1)
       Next
       Dim c(size - 1) As Integer
       Dim assign As Action(Of Integer, Integer) = Sub(u As Integer, root As Integer)
                                                       If vis(u) Then
                                                           vis(u) = False
                                                           c(u) = root
                                                           For Each v In t(u)
                                                               assign(v, root)
                                                           Next
                                                       End If
                                                   End Sub
       For Each u In l
           assign(u, u)
       Next
       Return c.ToList
   End Function
   Sub Main()
       Dim g = New List(Of List(Of Integer)) From {
           New List(Of Integer) From {1},
           New List(Of Integer) From {2},
           New List(Of Integer) From {0},
           New List(Of Integer) From {1, 2, 4},
           New List(Of Integer) From {3, 5},
           New List(Of Integer) From {2, 6},
           New List(Of Integer) From {5},
           New List(Of Integer) From {4, 6, 7}
       }
       Dim output = Kosaraju(g)
       Console.WriteLine("[{0}]", String.Join(", ", output))
   End Sub

End Module</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

Wren

Translation of: Go

<lang ecmascript>var kosaraju = Fn.new { |g|

   var gc = g.count
   // 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
   var vis = List.filled(gc, false)
   var l = List.filled(gc, 0)
   var x = gc                     // index for filling l in reverse order
   var t = List.filled(gc, null)  // transpose graph
   for (i in 0...gc) t[i] = []
   var visit // recursive function
   visit = Fn.new { |u|
       if (!vis[u]) {
           vis[u] = true
           for (v in g[u]) {
               visit.call(v)
               t[v].add(u)  // construct transpose
           }
           x = x - 1
           l[x] = u
       }
   }
   // 2. For each vertex u of the graph do visit.call(u).
   for (i in 0...gc) visit.call(i)  
   var c = List.filled(gc, 0) // result, the component assignment
   var assign // recursive function
   assign = Fn.new { |u, root|
       if (vis[u]) {  // repurpose vis to mean 'unassigned'
           vis[u] = false
           c[u] = root
           for (v in t[u]) assign.call(v, root)
       }
   }
   // 3: For each element u of l in order, do assign.call(u,u).
   for (u in l) assign.call(u, u)
   return c

}

var g = [ [1], [2], [0], [1, 2, 4], [3, 5], [2, 6], [5], [4, 6, 7] ] System.print(kosaraju.call(g))</lang>

Output:
[0, 0, 0, 3, 3, 5, 5, 7]

zkl

<lang zkl>const VISITED=0,ASSIGNED=1;

fcn visit(u,G,L){ // u is ((visited,assigned), (id,edges))

  u0:=u[0];
  if(u0[VISITED]) return();
  u0[VISITED]=True;
  foreach idx in (u[1][1,*]){ visit(G[idx],G,L) } // vist out-neighbours
  L.insert(0,u);	// prepend u to L

} fcn assign(u,root,G){ // u as above, root is a list of strong components

  u0:=u[0];
  if(u0[ASSIGNED]) return();
  root.append(u[1][0]);
  u0[ASSIGNED]=True;
  uid:=u[1][0];
  foreach v in (G){  // traverse graph to find in-neighbours, fugly
     n,ins := v[1][0],v[1][1,*];
     if(ins.holds(uid)) assign(G[n],root,G); // assign in-neighbour
  } 

} fcn kosaraju(graph){ // Use Tarjan's algorithm instead of this one

  // input: graph G = (V, Es)
  // output: set of strongly connected components (sets of vertices)
  // convert graph to ( (index,lowlink,onStack),(id,links)), ...)
  // sorted by id
  G:=List.createLong(graph.len(),0);
  foreach v in (graph){ G[v[0]]=T( List(False,False),v) }
  L:=List();
  foreach u in (G){ visit(u,G,L) }
  components:=List.createLong(graph.len(),List.copy,True);
  foreach u in (L){ assign(u,components[u[1][0]],G) }
  components=components.filter();
  println("List of strongly connected components:");
  foreach c in (components){ println(c.reverse().concat(",")) }
  return(components);

}</lang> <lang zkl> // graph from https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm

  // with vertices id zero based (vs 1 based in article)
  // ids start at zero and are consecutive (no holes), graph is unsorted

graph:= // ( (id, links/Edges), ...)

  T( T(0,1), T(2,0),     T(5,2,6), T(6,5),
     T(1,2), T(3,1,2,4), T(4,5,3), T(7,4,7,6) );

kosaraju(graph);</lang>

Output:
List of strongly connected components:
1,2,0
4,3
6,5
7