A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent nodes' numbers.
Output Specification:
For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print "Error: K components" where K is the number of connected components in the graph.
Sample Input 1:5 1 2 1 3 1 4 2 5Sample Output 1:
3 4 5Sample Input 2:
5 1 3 1 4 2 5 3 4Sample Output 2:
Error: 2 components
备注:刚开始用暴力解法,对每个点用BFS求出该点的深度,然后找最大的深度,结果有一个case超时网上查了一下,有简单的解法,一个图只要两遍BFS就能出结果。具体做法是:从任意一个点x出发用BFS(或DFS)找到离它最远的点集Y,然后从Y中任选一点y出发再用一次BFS(或DFS)找到离y最远的点的距离记为p,p即为最大深度。在做第二次BFS(或DFS)时记录每个节点的深度,找到所有深度为p的点,记为点集Z。合并Y和Z即为最终结果。
#include<iostream> #include<queue> #include<set> using namespace std; typedef struct node { //int height; int depth; bool visited; vector<int> neighbors; }NODE; void InitializeVisit(NODE *tree, int n_nodes) { for(int i=1;i<=n_nodes;i++) tree[i].visited = false; } // doing BFS from start_node and returns the last visited node // store the maximum depth in last visited node's depth field int BFS(int start_node,NODE *tree, int n_nodes) { queue<int> q; int last_visit_index = start_node; //initialize depth of each node for(int i=1;i<=n_nodes;i++) tree[i].depth = 0; q.push(start_node); tree[start_node].depth = 1; while(!q.empty()) { int node_id = q.front(); q.pop(); if(!tree[node_id].visited) { last_visit_index = node_id; tree[node_id].visited = true; NODE node = tree[node_id]; for(int i=0;i<(int)node.neighbors.size();i++) { NODE neighbor = tree[node.neighbors[i]]; if(!neighbor.visited) { //update depth tree[node.neighbors[i]].depth = node.depth+1; // parent's depth+1 q.push(node.neighbors[i]); } } } } return last_visit_index; } int main() { int n_nodes; set<int> ans; cin>>n_nodes; NODE *tree = new NODE[n_nodes+1]; for(int i=0;i<n_nodes-1;i++) { int a,b; cin>>a>>b; tree[a].neighbors.push_back(b); tree[b].neighbors.push_back(a); } //first judge whether the graph is a tree using BFS InitializeVisit(tree,n_nodes); int n_components = 0; for(int i=1;i<=n_nodes;i++) { if(!tree[i].visited) { BFS(i,tree,n_nodes); n_components++; } } if(n_components>1) { cout<<"Error: "<<n_components<<" components"<<endl; return 0; } //a tree case InitializeVisit(tree,n_nodes); int x=1,y,z; // random choose a node x (here we choose node 1) to find the furthest node it can reach // suppose the found node is y and their distance is maxdepth y = BFS(x,tree,n_nodes); int maxdepth = tree[y].depth; //cout<<"from x to y, maxdepth is: "<< maxdepth<<", last visit node is "<<y<<endl; for(int i=1;i<=n_nodes;i++) { if(tree[i].depth == maxdepth) ans.insert(i); } // then start from y to do another BFS, find the furthest node it can reach // suppose the found node is z and their distance is maxdepth InitializeVisit(tree,n_nodes); z=BFS(y,tree,n_nodes); maxdepth = tree[z].depth; //cout<<"from y to z, maxdepth is: "<< maxdepth<<", last visit node is "<<z<<endl; for(int i=1;i<=n_nodes;i++) { if(tree[i].depth == maxdepth) ans.insert(i); } for(set<int>::iterator it=ans.begin();it!=ans.end();it++) cout<<*it<<endl; return 0; }