diff --git a/src/main/java/com/thealgorithms/graph/Connected Components/Strongly Connected Components - Naive Approach/sccNaive.java b/src/main/java/com/thealgorithms/graph/Connected Components/Strongly Connected Components - Naive Approach/sccNaive.java new file mode 100644 index 000000000000..6b3e446d337c --- /dev/null +++ b/src/main/java/com/thealgorithms/graph/Connected Components/Strongly Connected Components - Naive Approach/sccNaive.java @@ -0,0 +1,81 @@ +import java.util.*; +public class sccNaive +{ + //Implementing the conventional DFS + public boolean isPath(HashMap> adj_list,int N,int visited[],int current_node,int destination) + { + if(current_node == destination) + { + return true; + } + List lists = adj_list.get(current_node); + int lists_size = lists.size(); + visited[current_node] = 1; + for(int i = 0;i < lists_size;i++) + { + if(visited[lists.get(i)] == 0) + { + if(isPath(adj_list,N,visited,lists.get(i),destination)) + { + return true; + } + + } + } + return false; + } + public Set> getOutput(HashMap> adj_list,int N) + { + Set> SCC_lists = new HashSet<>(); + for(int i = 1;i <= N;i++) + { + List neighbour_vertices = new ArrayList<>(); + for(int j = 1;j <= N;j++) + { + if(i != j) + { + int visited[] = new int[N+1]; + if(isPath(adj_list, N,visited,i,j)) + { + visited = new int[N+1]; + if(isPath(adj_list, N, visited, j, i)) + { + neighbour_vertices.add(j); + } + } + } + else + { + neighbour_vertices.add(i); + + } + } + SCC_lists.add(new ArrayList<>(neighbour_vertices)); + } + return SCC_lists; + } + public static void main(String[] args) { + Scanner rs = new Scanner(System.in); + HashMap> adj_list = new HashMap<>(); + int N = rs.nextInt(); + for(int i = 1;i <= N;i++) + { + adj_list.put(i,new ArrayList<>()); + } + for(int i = 1;i <= N;i++) + { + System.out.println("Number of neighbour vertices"); + int n_vertices = rs.nextInt(); + for(int j = 0;j < n_vertices;j++) + { + int vertices = rs.nextInt(); + List lists = adj_list.get(i); + lists.add(vertices); + } + } + System.out.println(adj_list); + sccNaive obj = new sccNaive(); + System.out.print(obj.getOutput(adj_list,N)); + rs.close(); + } +} \ No newline at end of file diff --git a/src/main/java/com/thealgorithms/graph/Connected Components/Strongly Connected Components - Kosaraju Algorithm/sccOptimized.java b/src/main/java/com/thealgorithms/graph/Connected Components/Strongly Connected Components - Kosaraju Algorithm/sccOptimized.java new file mode 100644 index 000000000000..907495b94cb8 --- /dev/null +++ b/src/main/java/com/thealgorithms/graph/Connected Components/Strongly Connected Components - Kosaraju Algorithm/sccOptimized.java @@ -0,0 +1,99 @@ +import java.util.*; + +public class sccOptimized { + + public void btrack(HashMap> adjList, int[] visited, Stack dfsCallsNodes, int currentNode) { + visited[currentNode] = 1; + for (int i = 0; i < adjList.get(currentNode).size(); i++) { + int neighbor = adjList.get(currentNode).get(i); + if (visited[neighbor] == -1) { + btrack(adjList, visited, dfsCallsNodes, neighbor); + } + } + dfsCallsNodes.add(currentNode); // Add node after finishing DFS on all neighbors + } + + public void btrack2(HashMap> adjRevList, int[] visited, int currentNode, List newScc) { + visited[currentNode] = 1; + newScc.add(currentNode); // Add node to the current SCC + for (int i = 0; i < adjRevList.get(currentNode).size(); i++) { + int neighbor = adjRevList.get(currentNode).get(i); + if (visited[neighbor] == -1) { + btrack2(adjRevList, visited, neighbor, newScc); + } + } + } + + public int getOutput(HashMap> adjList, int N) { + int[] visited = new int[N]; + Arrays.fill(visited, -1); + Stack dfsCallsNodes = new Stack<>(); + + // First DFS pass to fill the stack with the finishing times of nodes + for (int i = 0; i < N; i++) { + if (visited[i] == -1) { + btrack(adjList, visited, dfsCallsNodes, i); + } + } + + System.out.println("Stack of nodes by finish time: " + dfsCallsNodes); + + // Reverse the graph + HashMap> adjRevList = new HashMap<>(); + for (int i = 0; i < N; i++) { + adjRevList.put(i, new ArrayList<>()); + } + + for (int i = 0; i < N; i++) { + for (int neighbor : adjList.get(i)) { + adjRevList.get(neighbor).add(i); // Reverse edge + } + } + + // Second DFS on the reversed graph + Arrays.fill(visited, -1); + int stronglyConnectedComponents = 0; + List> sccs = new ArrayList<>(); + + while (!dfsCallsNodes.isEmpty()) { + int node = dfsCallsNodes.pop(); + if (visited[node] == -1) { + List newScc = new ArrayList<>(); + btrack2(adjRevList, visited, node, newScc); + sccs.add(newScc); + stronglyConnectedComponents++; + } + } + + // Print the found SCCs + System.out.println("Strongly Connected Components: " + sccs); + return stronglyConnectedComponents; + } + + public static void main(String[] args) { + Scanner rs = new Scanner(System.in); + HashMap> adjList = new HashMap<>(); + int N = rs.nextInt(); // Number of nodes + + // Initialize adjacency list + for (int i = 0; i < N; i++) { + adjList.put(i, new ArrayList<>()); + } + + // Input graph data + for (int i = 0; i < N; i++) { + System.out.println("Number of neighbor vertices for node " + i + ": "); + int nVertices = rs.nextInt(); + for (int j = 0; j < nVertices; j++) { + int neighbor = rs.nextInt(); + adjList.get(i).add(neighbor); + } + } + + System.out.println("Adjacency list: " + adjList); + + sccOptimized obj = new sccOptimized(); + System.out.println("Number of SCCs: " + obj.getOutput(adjList, N)); + rs.close(); + } +}