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
使用并查集判断子图数目。
若子图数为1,对每个结点进行dfs可得到最大深度的点。这种写法有一个case超时。
为了避免大数据超时,只使用两次dfs,第一次对结点1进行dfs,得到一个候选结点集合tbd,第二次对候选结点集合中的随意一个结点进行dfs,得到第二个候选结点集合tbd1,对两个集合进行合并和去重即为结果。(事实上本题可以转换为:对于以1号结点为根的树,输出树中相距最远的两个结点,若有多个结果,将满足条件的结点从小到大输出。易知对根结点进行1次dfs,最深的叶子结点肯定是候选结点,若这些叶子结点分布在根结点的两个子树,则相互匹配;若这些叶子结点分布在根结点的同一颗子树,则其匹配的结点可能在根结点的另一棵子树,这就是原题进行第二次dfs的原因)
<pre name="code" class="cpp">/*2015.7.22cyq*/ #include <iostream> #include <vector> #include <algorithm> #include <fstream> using namespace std; //ifstream fin("case1.txt"); //#define cin fin int findroot(vector<int> &root,int a){ if(root[a]!=a) root[a]=findroot(root,root[a]);//路径压缩,将多跳后的根作为a的直接上级 return root[a]; } int graphNum(const vector<vector<bool> > &edges,int N){ vector<int> root; for(int i=0;i<=N;i++) root.push_back(i);//一开始每个结点的根结点都是自身 int result=N; //最多有N个子图 for(int i=1;i<=N;i++){ for(int j=i+1;j<=N;j++){ if(edges[i][j]){ int ar=findroot(root,i); int br=findroot(root,j); if(ar!=br){//不在同一个子图 result--;//该边使得子图数减一 root[ar]=br;//连接两个子图 } } } } return result; } void dfs(vector<vector<bool> > &edges,int &N,int start,int &depth,int &maxD,vector<int> &tbd){ depth++; if(depth>maxD){ maxD=depth; tbd.clear(); tbd.push_back(start); }else if(depth==maxD){ tbd.push_back(start); } for(int i=1;i<=N;i++){ if(edges[start][i]){ edges[start][i]=false; edges[i][start]=false; dfs(edges,N,i,depth,maxD,tbd); edges[start][i]=true; edges[i][start]=true; } } depth--; } int main(){ int N; cin>>N; if(N==1){ cout<<1; return 0; } vector<vector<bool> > edges(N+1,vector<bool>(N+1,false)); int a,b; for(int i=1;i<N;i++){ cin>>a>>b; edges[a][b]=true; edges[b][a]=true; } int gn=graphNum(edges,N); if(gn>1){ printf("Error: %d components",gn); return 0; } //对1号结点进行一次dfs, int start=1;//dfs起点 int depth=0;//dfs中动态变化的深度 int maxD=0;//最大深度 vector<int> tbd;//存储候选结点 dfs(edges,N,start,depth,maxD,tbd); int deptest=maxD;//记录最大深度 //对其中一个候选结点进行dfs start=tbd[0]; depth=0; maxD=0; vector<int> tbd1; dfs(edges,N,start,depth,maxD,tbd1); for(auto it=tbd1.begin();it!=tbd1.end();++it) tbd.push_back(*it); sort(tbd.begin(),tbd.end()); tbd.resize(unique(tbd.begin(),tbd.end())-tbd.begin()); for(auto it=tbd.begin();it!=tbd.end();it++) cout<<*it<<endl; return 0; }