public class UndirectedDepthFirstMatrix2 { int numVertices; // Number of vertices, given as input. int numEdges; // We keep track of the number of edges. boolean isWeighted; // Is this a weighted graph? boolean useMatrix = true; // Adjacency-matrix or list? double [][] adjMatrix; // The matrix. Note: we use "double" to store // "double" weights, if the graph is weighted. int[] visitOrder; // visitOrder[i] = the i-th vertex to be visited in order. int visitCount; // We will track visits with this counter. int[] completionOrder; // completionOrder[i] = the i-th vertex that completed. int completionCount; // For tracking. int numTreeEdges; // Number of edges in depth-first tree. int numBackEdges; // Number of "back" edges (to a vertex with an earlier visit#). int numDownEdges; // Number of "down" edges (to a vertex with a later visit#). int[] componentLabels; // componentLabels[i] = which component vertex i belongs to. int currentComponentLabel; // Need to track this as we proceed with depth-first search. public void initialize (int numVertices, boolean isWeighted) { // Store: this.numVertices = numVertices; this.isWeighted = isWeighted; // Use desired representation. if (useMatrix) { // Create the adjacency matrix. adjMatrix = new double [numVertices][]; for (int i=0; i= numVertices) ) return true; return false; } // Insert a given input edge. public void insertUndirectedEdge (int startVertex, int endVertex, double weight) { // Check whether vertex is valid. if ( outOfBounds (startVertex) || outOfBounds (endVertex) ) { System.out.println ("ERROR: out of bounds: start=" + startVertex + " end=" + endVertex); return; } // Matrix representation: if (useMatrix) { // If already inserted, flag an error. if (adjMatrix[startVertex][endVertex] != 0) { System.out.println ("ERROR: edge already inserted: (" + startVertex + "," + endVertex +")"); return; } // Unweighted graph: use weight 1.0. if (! isWeighted) { adjMatrix[startVertex][endVertex] = 1.0; adjMatrix[endVertex][startVertex] = 1.0; // Remove for directed graphs } else { adjMatrix[startVertex][endVertex] = weight; adjMatrix[endVertex][startVertex] = weight; // Remove for directed graphs } numEdges ++; return; } // end-use-Matrix. // Adjacency-list representation ... } // Initialize visit information before search. void initSearch () { // IMPORTANT: all initializations will use "-1". We will test // equality with "-1", so it's important not to change this cavalierly. visitCount = -1; completionCount = -1; for (int i=0; i 0) && (i != v) ) { if (visitOrder[i] == -1) { // i is an unvisited neighbor that is not v. numTreeEdges++; depthFirstMatrixRecursive (v, i); } else if (i != fromVertex) { // Avoid trivial case. if (visitOrder[i] < visitOrder[v]) { // Back edge processing: (v,i) is a backedge. numBackEdges ++; } else { // Down edge processing: (v,i) is a downedge. numDownEdges ++; } } // end-already-visited else-portion. } // end-if } // 3. After returning from recursion(s), set the post-order or "completion" order number. completionCount++; completionOrder[v] = completionCount; } }