/*
Recently saw a Google pen question, "known to a undirected non-circular connected graph t all vertices and edges of information,
Now you need to convert it to a tree, requiring the minimum depth of the tree, design an algorithm to find all the
The root node of the tree and analyze the space-time complexity (describing the algorithm, without code) "
In fact, given a non-connected graph, which vertex is the root of the tree can get the smallest depth, the idea is relatively simple,
There are two main steps:
(1) First select the number 1th node as the root, the DFS, the DFS when the COUNTV value of each node is evaluated, indicating
Maximum depth of subtree with current node as tree root +1
(2) Perform the second pass of DFS, DP, for each adjacency point of node I j,maxdepth (i, j) represents a subtree with I as the root, along with J
The maximum depth of the subtree that is formed, then
MaxDepth (i, j) = Countv[j], when J has not been accessed
Max (MaxDepth (j, K)) + 1, K is the neighbor node of J and K!=i, when J is accessed
The above formula is easy to understand, when J has not been visited, it is using the results of (1), otherwise it is using DP utilization
The current state of the neighbor to calculate its own state
The final answer is: Min (max (MaxDepth (i, J), for all I ' s neighbour J)), for all nodes I
(1) The time complexity is O (v + e), (2) The time complexity is O (v * e), so the overall time complexity is O (v * e)
*/
#include <iostream> #define Max_n using namespace std; struct head//adjacency table {int toid;//edge of the to Node ID int maxDepth;//denotes the root of I, the maximum depth of the connected J-Tree is head *next; Head () {toid = maxDepth = 0; n ext = NULL; }}*heads[max_n]; int Countv[max_n]; The first time Dfs is logged with the current node as the maximum depth of subtree +1 int res[max_n], num, mindepthval; Records the final result, the number of nodes with minimum maximum degree mindepthval and the node bool V[max_n]; Whether the marker node is accessed by int noden; Number of nodes//Initialize void init () {for (int i = 0; i < max_n; i++) {countv[i] = res[i] = 0; V[i] = false; head *curptr = heads[ I]; while (curptr! = null) {Head *tempptr = curptr->next; Delete curptr; curptr = tempptr;} Heads[i] = null; }}//Insert an edge void Insertedge (int from, int. to) into the storefront table {Head *newhead = new head (); newhead->toid = to; Newhead->next = Heads[from]; Heads[from] = Newhead; }//First time DFS calculates account int getaccount (int id) {//tag access v[id] = true;//maximum depth +1 initial value is 1 int maxd = 1;//traverse the current node's frontage table head *curptr = Heads[id]; while (CURPTR) {//adjacency point ID int toid = curptr->toid; Curptr = curptr->next; if (v[toid]) Continue int tempd = Getaccount (toid); Update the value of maximum depth +1 if (tempd + 1 > Maxd) maxd = tempd + 1; }//Record result return countv[id] = Maxd; }//Second time DPF calculates the maximum depth of the tree with each node as the root of void getanswer (int id) {//if access is no longer accessible if (V[id]) return;//mark an unreachable node as Access state V[id] = true; Head *CU RPTR = Heads[id]; The maximum depth of the outlier is 0, so the initial value of the maxd is 0 int maxd = 0; Traversal adjacency table while (curptr) {//Neighbor Node ID int toid = curptr->toid;//If the current neighbor point has not been processed, Then it is necessary to calculate the maximum depth of the subtree consisting of the current node ID and its neighbor node toid (!v[toid]) {//Record curptr->maxdepth = Countv[toid] With the COUNTV array generated by the first DFS, if ( Countv[toid] > Maxd) maxd = countv[toid]; }//If the current neighbor point has been processed, it is necessary to take advantage of the result of the current neighbor node toid to get the status value of the ID, else {//traverse all neighbor Toidd of toid. Toidd constituted subtree +toid+id as a new subtree int maxdd = 1; Head *tempptr = heads[toid]; while (tempptr) {int Toidd = tempptr->toid; if (Toidd! = ID) {if (tempptr->maxdepth + 1 > Maxdd) maxdd = tempptr-& Gt;maxdepth + 1; } tempptr = tempptr->next; } curptr->maxdepth = Maxdd; if (Maxdd > Maxd) maxd = MAXDD; } curptr = curptr->next; }//Update results if (Maxd < mindepthval) {Mindepthval= Maxd; num = 1; RES[0] = ID; } else if (Maxd = = Mindepthval) {res[num++] = ID;}//dfs curptr = Heads[id]; while (curptr) {int toid = curptr->toid; getanswer (toid); curptr = curptr->next;}} int main () {int i, from, to; int root = 1; while (Cin>>noden && noden! = NULL) {init (); for (i = 1; i < n OdeN; i++) {cin>>from>>to; Insertedge (from, to); Insertedge (to, from);} getaccount (Root); memset (V, 0, sizeof (v)); num = 0; Mindepthval = Int_max; Getanswer (root); cout<< "Answer" <<endl; cout<< "Depth" <<minDepthVal<<endl; cout<< "Node"; for (i = 0; i < num; i++) cout<<res[i]<< ""; cout<<endl; } return 0; }