首页 > 代码库 > HDU 1269: 迷宫城堡

HDU 1269: 迷宫城堡

 

 迷宫城堡


///@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

 

HDU 1269: 迷宫城堡