- Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathKosarajuAlgorithm.java
More file actions
Latest commit
119 lines (104 loc) · 5.13 KB
/
Copy pathKosarajuAlgorithm.java
File metadata and controls
119 lines (104 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
packageGraph;
importjava.util.ArrayList;
importjava.util.Scanner;
importjava.util.Stack;
/**
* TC = O(N+E)
* SC = O(N+E) + O(N) + O(N) (for transposeGraph, Visited array, Stack)
* Given a graph and the number of nodes present in the graph.
* We have to find all the strongly connected components.
* Applications: SCC algorithms can be used as a first step in many graph
* algorithms that work only on strongly connected graph. In social networks,
* a group of people are generally strongly connected (For example, students
* of a class or any other common place). Many people in these groups generally
* like some common pages or play common games. The SCC algorithms can be used
* to find such groups and suggest the commonly liked pages or games to the people
* in the group who have not yet liked commonly liked a page or played a game.
*/
publicclassKosarajuAlgorithm {
publicstaticvoidmain(String[] args) {
Scannersc = newScanner(System.in);
System.out.println("Enter the number of testcases:");
intnumberOfTestcases = sc.nextInt();
while (numberOfTestcases-- > 0) {
ArrayList<ArrayList<Integer>> adjacencyList = newArrayList<>();
// Taking input for number of nodes
System.out.println("Enter the number of nodes:");
intnumberOfNodes = sc.nextInt();
// initializing adjacencyList with new ArrayList<>()
for (inti = 1; i <= numberOfNodes + 1; i++) {
adjacencyList.add(newArrayList<>());
}
// taking input of adjacent nodes of particular node
for (inti = 1; i <= numberOfNodes; i++) {
System.out.println("Enter number of adjacent nodes to the node : " + i);
intcountOfAdjacentNodes = sc.nextInt();
// taking input of the particular adjacent nodes to the node i
System.out.println("Enter adjacent nodes:");
for (intj = 0; j < countOfAdjacentNodes; j++) {
// taking input of adjacent node
intadjacentNode = sc.nextInt();
// adding the adjacent node to the particular node i
adjacencyList.get(i).add(adjacentNode);
}
}
// method calling
kosarajuAlgo(adjacencyList, numberOfNodes);
System.out.println();
}
}
publicstaticvoidkosarajuAlgo(ArrayList<ArrayList<Integer>> adjacencyList, intnumberOfNodes) {
// STEP 1 : Perform topological sort in the given graph
boolean[] visited = newboolean[numberOfNodes + 1]; // for marking the nodes as visited
Stack<Integer> topoSort = newStack<>(); // stack for DFS : storing topological sorting of the nodes
// calling DFS
for (intnode = 1; node <= numberOfNodes; node++) {
if (!visited[node]) { // if the node is not visited then run DFS call
dfs(node, topoSort, adjacencyList, visited);
}
}
// STEP 2 : Transpose the given graph (Reverse the direction of the edges)
ArrayList<ArrayList<Integer>> transposeGraph = newArrayList<>();
for (inti = 1; i <= numberOfNodes + 1; i++) {
transposeGraph.add(newArrayList<>());
}
// visiting all nodes in the graph
for (intnode = 1; node <= numberOfNodes; node++) {
visited[node] = false; // unvisit the node because it is already visited in first step so remove it
for (IntegeradjacentNode : adjacencyList.get(node)) {
transposeGraph.get(adjacentNode).add(node); // reversing the direction of the edge
}
}
// STEP 3 : Run reverse DFS according to the topological sort
while (!topoSort.isEmpty()) {
intcurrentNode = topoSort.pop();
// if the node is not visited
if (!visited[currentNode]) {
System.out.print("Strong connected component : ");
reverseDFS(currentNode, transposeGraph, visited); // calling reverse DFS
System.out.println();
}
}
}
// Normal DFS method
publicstaticvoiddfs(intnode, Stack<Integer> topoSort, ArrayList<ArrayList<Integer>> adjacencyList, boolean[] visited) {
visited[node] = true;
for (IntegeradjacentNode : adjacencyList.get(node)) {
if (!visited[adjacentNode]) {
dfs(adjacentNode, topoSort, adjacencyList, visited);
}
}
topoSort.push(node);
}
// Reversed DFS method for transpose graph
publicstaticvoidreverseDFS(intcurrentNode, ArrayList<ArrayList<Integer>> transposeGraph, boolean[] visited) {
visited[currentNode] = true;
// printing elements of the SCC
System.out.print(currentNode + " ");
for (IntegeradjacentNode : transposeGraph.get(currentNode)) {
if (!visited[adjacentNode]) {
reverseDFS(adjacentNode, transposeGraph, visited);
}
}
}
}