// Stephen Fulwider
//	A sample program to show working examples of Depth First Search (DFS)

public class DFS
{

	public static void main(String[] args)
	{
		new DFS_BFS(); // I like doing things this way...
	}

	int N; // number of vertices in the graph
	boolean[][] G; // the graph as an adjacency matrix
				   // G[i][j] is true if there is an edge from i to j

	DFS_BFS()
	{
		setupGraph();
		System.out.println("------------------------------");
		System.out.println();

		// perform a DFS on the graph
		DFS();
		System.out.println();
		System.out.println("------------------------------");
		System.out.println();

		// perform a BFS on the graph
		BFS();
		System.out.println();
		System.out.println("------------------------------");
		System.out.println();
		System.out.println("All done - have a good day!");
	}

	// initial setup of the graph
	void setupGraph()
	{
		// set up a graph with 8 vertices + 3 components that looks like:
		/*
			0 --- 1        5---6
			| \    \       |  /
			|  \    \      | /
			2   3----4     7
		*/
		N=8;
		G=new boolean[N][N];
		// notice that for each edge G[i][j] == G[j][i]
		// this means that the graph is undirected
		G[0][1]=G[1][0]=true; G[0][2]=G[2][0]=true; G[0][3]=G[3][0]=true;
		G[1][4]=G[4][1]=true; G[3][4]=G[4][3]=true; G[5][6]=G[6][5]=true;
		G[5][7]=G[7][5]=true; G[6][7]=G[7][6]=true;
	}

	// perform a DFS on the graph G
	void DFS()
	{
		// a visited array to mark visited vertices in DFS
		boolean[] V=new boolean[N];
		int numComponets=0; // the number of components in the graph

		// do the DFS from each node not already visited
		for (int i=0; i<N; ++i)
			if (!V[i])
			{
				++numComponets;
				System.out.printf("DFS for component %d starting at node %d%n",numComponets,i);
				DFS(i,V);
			}

		System.out.println();
		System.out.printf("Finished DFS - found %d components.%n", numComponets);
	}

	// perform a DFS starting at node at (works recursively)
	void DFS(int at, boolean[] V)
	{
		System.out.printf("At node %d in the DFS%n",at);

		// mark that we are visiting this node
		V[at]=true;

		// recursively visit every node connected yet to be visited
		for (int i=0; i<N; ++i)
			if (G[at][i] && !V[i])
			{
				System.out.printf("Going to node %d...",i);
				DFS(i,V);
			}
		System.out.printf("Done processing node %d%n", at);
	}
}
