Un grafo dirigido es fuertemente conexo si existe un camino entre todos los pares de vértices. Un componente fuertemente conectado ( SCC ) de un gráfico dirigido es un subgrafo máximo fuertemente conectado. Por ejemplo, hay 3 SCC en el siguiente gráfico.
C++
// C++ Implementation of Kosaraju's algorithm to print all SCCs #include <iostream> #include <list> #include <stack> using namespace std; class Graph { int V; // No. of vertices list<int> *adj; // An array of adjacency lists // Fills Stack with vertices (in increasing order of finishing // times). The top element of stack has the maximum finishing // time void fillOrder(int v, bool visited[], stack<int> &Stack); // A recursive function to print DFS starting from v void DFSUtil(int v, bool visited[]); public: Graph(int V); void addEdge(int v, int w); // The main function that finds and prints strongly connected // components void printSCCs(); // Function that returns reverse (or transpose) of this graph Graph getTranspose(); }; Graph::Graph(int V) { this->V = V; adj = new list<int>[V]; } // A recursive function to print DFS starting from v void Graph::DFSUtil(int v, bool visited[]) { // Mark the current node as visited and print it visited[v] = true; cout << v << " "; // Recur for all the vertices adjacent to this vertex list<int>::iterator i; for (i = adj[v].begin(); i != adj[v].end(); ++i) if (!visited[*i]) DFSUtil(*i, visited); } Graph Graph::getTranspose() { Graph g(V); for (int v = 0; v < V; v++) { // Recur for all the vertices adjacent to this vertex list<int>::iterator i; for(i = adj[v].begin(); i != adj[v].end(); ++i) { g.adj[*i].push_back(v); } } return g; } void Graph::addEdge(int v, int w) { adj[v].push_back(w); // Add w to v’s list. } void Graph::fillOrder(int v, bool visited[], stack<int> &Stack) { // Mark the current node as visited and print it visited[v] = true; // Recur for all the vertices adjacent to this vertex list<int>::iterator i; for(i = adj[v].begin(); i != adj[v].end(); ++i) if(!visited[*i]) fillOrder(*i, visited, Stack); // All vertices reachable from v are processed by now, push v Stack.push(v); } // The main function that finds and prints all strongly connected // components void Graph::printSCCs() { stack<int> Stack; // Mark all the vertices as not visited (For first DFS) bool *visited = new bool[V]; for(int i = 0; i < V; i++) visited[i] = false; // Fill vertices in stack according to their finishing times for(int i = 0; i < V; i++) if(visited[i] == false) fillOrder(i, visited, Stack); // Create a reversed graph Graph gr = getTranspose(); // Mark all the vertices as not visited (For second DFS) for(int i = 0; i < V; i++) visited[i] = false; // Now process all vertices in order defined by Stack while (Stack.empty() == false) { // Pop a vertex from stack int v = Stack.top(); Stack.pop(); // Print Strongly connected component of the popped vertex if (visited[v] == false) { gr.DFSUtil(v, visited); cout << endl; } } } // Driver program to test above functions int main() { // Create a graph given in the above diagram Graph g(5); g.addEdge(1, 0); g.addEdge(0, 2); g.addEdge(2, 1); g.addEdge(0, 3); g.addEdge(3, 4); cout << "Following are strongly connected components in " "given graph \n"; g.printSCCs(); return 0; }
Java
// Java implementation of Kosaraju's algorithm to print all SCCs import java.io.*; import java.util.*; import java.util.LinkedList; // This class represents a directed graph using adjacency list // representation class Graph { private int V; // No. of vertices private LinkedList<Integer> adj[]; //Adjacency List //Constructor Graph(int v) { V = v; adj = new LinkedList[v]; for (int i=0; i<v; ++i) adj[i] = new LinkedList(); } //Function to add an edge into the graph void addEdge(int v, int w) { adj[v].add(w); } // A recursive function to print DFS starting from v void DFSUtil(int v,boolean visited[]) { // Mark the current node as visited and print it visited[v] = true; System.out.print(v + " "); int n; // Recur for all the vertices adjacent to this vertex Iterator<Integer> i =adj[v].iterator(); while (i.hasNext()) { n = i.next(); if (!visited[n]) DFSUtil(n,visited); } } // Function that returns reverse (or transpose) of this graph Graph getTranspose() { Graph g = new Graph(V); for (int v = 0; v < V; v++) { // Recur for all the vertices adjacent to this vertex Iterator<Integer> i =adj[v].listIterator(); while(i.hasNext()) g.adj[i.next()].add(v); } return g; } void fillOrder(int v, boolean visited[], Stack stack) { // Mark the current node as visited and print it visited[v] = true; // Recur for all the vertices adjacent to this vertex Iterator<Integer> i = adj[v].iterator(); while (i.hasNext()) { int n = i.next(); if(!visited[n]) fillOrder(n, visited, stack); } // All vertices reachable from v are processed by now, // push v to Stack stack.push(new Integer(v)); } // The main function that finds and prints all strongly // connected components void printSCCs() { Stack stack = new Stack(); // Mark all the vertices as not visited (For first DFS) boolean visited[] = new boolean[V]; for(int i = 0; i < V; i++) visited[i] = false; // Fill vertices in stack according to their finishing // times for (int i = 0; i < V; i++) if (visited[i] == false) fillOrder(i, visited, stack); // Create a reversed graph Graph gr = getTranspose(); // Mark all the vertices as not visited (For second DFS) for (int i = 0; i < V; i++) visited[i] = false; // Now process all vertices in order defined by Stack while (stack.empty() == false) { // Pop a vertex from stack int v = (int)stack.pop(); // Print Strongly connected component of the popped vertex if (visited[v] == false) { gr.DFSUtil(v, visited); System.out.println(); } } } // Driver method public static void main(String args[]) { // Create a graph given in the above diagram Graph g = new Graph(5); g.addEdge(1, 0); g.addEdge(0, 2); g.addEdge(2, 1); g.addEdge(0, 3); g.addEdge(3, 4); System.out.println("Following are strongly connected components "+ "in given graph "); g.printSCCs(); } } // This code is contributed by Aakash Hasija
Python
# Python implementation of Kosaraju's algorithm to print all SCCs from collections import defaultdict #This class represents a directed graph using adjacency list representation class Graph: def __init__(self,vertices): self.V= vertices #No. of vertices self.graph = defaultdict(list) # default dictionary to store graph # function to add an edge to graph def addEdge(self,u,v): self.graph[u].append(v) # A function used by DFS def DFSUtil(self,v,visited): # Mark the current node as visited and print it visited[v]= True print v, #Recur for all the vertices adjacent to this vertex for i in self.graph[v]: if visited[i]==False: self.DFSUtil(i,visited) def fillOrder(self,v,visited, stack): # Mark the current node as visited visited[v]= True #Recur for all the vertices adjacent to this vertex for i in self.graph[v]: if visited[i]==False: self.fillOrder(i, visited, stack) stack = stack.append(v) # Function that returns reverse (or transpose) of this graph def getTranspose(self): g = Graph(self.V) # Recur for all the vertices adjacent to this vertex for i in self.graph: for j in self.graph[i]: g.addEdge(j,i) return g # The main function that finds and prints all strongly # connected components def printSCCs(self): stack = [] # Mark all the vertices as not visited (For first DFS) visited =[False]*(self.V) # Fill vertices in stack according to their finishing # times for i in range(self.V): if visited[i]==False: self.fillOrder(i, visited, stack) # Create a reversed graph gr = self.getTranspose() # Mark all the vertices as not visited (For second DFS) visited =[False]*(self.V) # Now process all vertices in order defined by Stack while stack: i = stack.pop() if visited[i]==False: gr.DFSUtil(i, visited) print"" # Create a graph given in the above diagram g = Graph(5) g.addEdge(1, 0) g.addEdge(0, 2) g.addEdge(2, 1) g.addEdge(0, 3) g.addEdge(3, 4) print ("Following are strongly connected components " + "in given graph") g.printSCCs() #This code is contributed by Neelam Yadav
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA