标签:stat passing acm more with res ini direct family
///@author Sycamore, ZJNU ///@date 7/31/2017 ///@ref geeksforgeeks // A C++ program to find strongly connected components in a given // directed graph using Tarjan‘s algorithm (single DFS) //Time Complexity: mainly calls DFS, DFS takes O(V + E) for a graph //represented using adjacency list. #include<iostream> #include<algorithm> #include <list> #include<vector> #include <stack> #define NIL -1 using namespace std; typedef vector<int> VI; typedef vector<bool> VB; typedef vector<list<int>> VLI; typedef stack<int> SI; // A class that represents an directed graph class Graph { int V; // No. of vertices VLI adj; // A dynamic array of adjacency lists VI disc, low; VB stackMember; SI st; // A Recursive DFS based function used by SCC() void SCCUtil(int, int &); public: Graph(int V) // Constructor { this->V = V; adj.resize(V); } void addEdge(int v, int w) // function to add an edge to graph { adj[v].push_back(w); } int SCC(); // prints strongly connected components }; // A recursive function that finds and prints strongly connected // components using DFS traversal // u --> The vertex to be visited next // disc --> Stores discovery times of visited vertices // low -- >> earliest visited vertex (the vertex with minimum // discovery time) that can be reached from subtree // rooted with current vertex // st -- >> To store all the connected ancestors (could be part // of SCC) // stackMember[] --> bit/index array for faster check whether // a node is in stack void Graph::SCCUtil(int u, int & SCC_num) { // A static variable is used for simplicity, we can avoid use // of static variable by passing a pointer. static int time = 0; // Initialize discovery time and low value disc[u] = low[u] = ++time; st.push(u); stackMember[u] = true; // Go through all vertices adjacent to this for (auto v : adj[u]) { // v is current adjacent of ‘u‘ // If v is not visited yet, then recur for it if (disc[v] == -1) { SCCUtil(v, SCC_num); // Check if the subtree rooted with ‘v‘ has a // connection to one of the ancestors of ‘u‘ // Case 1 (per above discussion on Disc and Low value) low[u] = min(low[u], low[v]); } // Update low value of ‘u‘ only of ‘v‘ is still in stack // (i.e. it‘s a back edge, not cross edge). // Case 2 (per above discussion on Disc and Low value) else if (stackMember[v] == true) low[u] = min(low[u], disc[v]); } // head node found, pop the stack and print an SCC int w = 0; // To store stack extracted vertices if (low[u] == disc[u]) { SCC_num++; while (st.top() != u) { w = st.top(); //cout << w << " "; //print current SCC-----print stackMember[w] = false; st.pop(); } //w = st.top();//print u------------------------print //cout << w << "\n"; stackMember[w] = false; st.pop(); } } // The function to do DFS traversal. It uses SCCUtil() and //returns the number of SCCs in this graph int Graph::SCC() { int SCC_num = 0; // Initialize disc and low, and stackMember arrays disc.resize(V, NIL); low.resize(V, NIL); stackMember.resize(V); // Call the recursive helper function to find strongly // connected components in DFS tree with vertex ‘i‘ for (int i = 0; i < V; i++) if (disc[i] == NIL) { SCCUtil(i, SCC_num); if (SCC_num > 1) return false; } return SCC_num == 1; //return SCC_num; } // Driver program to test above function int main() { ios::sync_with_stdio(false); int N, M, i, j; while (cin >> N >> M && (M || N)) { Graph g(N); while (M--) { cin >> i >> j; g.addEdge(i - 1, j - 1); } cout << (g.SCC() ? "Yes" : "No") << ‘\n‘; } return 0; }pasting
标签:stat passing acm more with res ini direct family
原文地址:http://www.cnblogs.com/zjnu/p/7261132.html