1021. Deepest Root (25)

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 5

Sample Output 1:

3
4
5

Sample Input 2:

5
1 3
1 4
2 5
3 4

Sample Output 2:

Error: 2 components

问题分析:

  判断连通量时,可通过广度或深度遍历+做标记的方法实现。

  求树的最大深度,可转化为求节点之间的最远距离

  首先可以任意节点(如1号节点)为根节点,创建树结构,最远的距离一定存在于叶节点之间。

  对树中的任意非叶节点Ni存在如下两种情况:

  1.以Ni为根节点的子树中可能含有完整的最长节点路径,即存在两个端节点均在Ni为根的子树中的最长节点路径

  2.以Ni为根节点的子树中可能含有部分最长节点路径,即存在一个端节点在该子树中,且该端节点一定是该子树中深度最大的节点(可能有多个),另一个端节点在子树外

算法思路:

  1. 判断连通性

  2. 以1号节点为根节点,建树

  3. 深度(或广度)遍历,对各个节点,记录以该节点为根的子树中最深和次深叶节点的深度,并计算可能在该子树中形成的完整最长路径长度

    最长路径=次深叶节点深度+最深叶节点深度+1

  4. 遍历所有的节点后,便可比较得到最长路径长度

  5. 从根节点开始遍历,将深度约束下放,如果当前节点为根的子树中存在完整最长路径,则需要将最深和次深节点的深度分别与当前深度约束比较,取较小值

  6. 遇到叶节点,判断是否满足深度约束即可,若满足,加入结果队列

  7. 对根节点(1号节点)特殊考虑

  8. 将结果队列排序输出

 

  以下代码分别给出了BFS和DFS的版本实现。

代码:

  1 #include<stdlib.h>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<vector>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 struct Node
  9 {
 10     int from;
 11     int to;
 12     int next;
 13     int prev;
 14 };
 15 struct Status
 16 {
 17     int id;
 18     int pno;
 19     int mlen;
 20     int mslen;
 21     int m1;
 22     int m2;
 23     int minlen;
 24 };
 25 Node tree[20010];
 26 int st[10010],ed[10010];
 27 int flag[10010];
 28 int N;
 29 int pn;
 30 Status nodestatus[10010];
 31 int maxlen;
 32 vector<int> nids;
 33 bool cmp(int &a,int &b)
 34 {
 35     return a<b;
 36 }
 37 void addToTree(int a,int b)
 38 {
 39     Node node;
 40     node.from=a;
 41     node.to=b;
 42     node.next=0;
 43     node.prev=0;
 44     ++pn;
 45     if(st[a]==0)
 46     {
 47         st[a]=pn;
 48     }
 49     else
 50     {
 51         int prev=ed[a];
 52         tree[prev].next=pn;
 53         node.prev=prev;
 54     }
 55     ed[a]=pn;
 56     tree[pn]=node;
 57 }
 58 int dfs(int si)
 59 {
 60     flag[si]=1;
 61     int treeid=st[si];
 62     int count=1;
 63     while(treeid!=0)
 64     {
 65         int b=tree[treeid].to;
 66         if(flag[b]==0)
 67         {
 68             count+=dfs(b);
 69         }
 70         treeid=tree[treeid].next;
 71     }
 72     return count;
 73 }
 74 
 75 int dfs_1(int si)
 76 {
 77     flag[si]=1;
 78     int treeid=st[si];
 79     int ml1=0,ml2=0;
 80     while(treeid!=0)
 81     {
 82         int b=tree[treeid].to;
 83         if(flag[b]==0)
 84         {
 85             nodestatus[b].pno=si;
 86             int mlt;
 87             mlt=dfs_1(b);
 88             if(ml1<=mlt)
 89             {
 90                 ml2=ml1;
 91                 ml1=mlt;
 92             }
 93             else if(ml2<mlt)
 94             {
 95                 ml2=mlt;
 96             }
 97         }
 98         treeid=tree[treeid].next;
 99     }
100     nodestatus[si].m1=ml1;
101     nodestatus[si].m2=ml2;
102     nodestatus[si].mlen=ml1+ml2+1;
103     nodestatus[si].mslen=ml1+1;
104     if(maxlen<nodestatus[si].mlen)
105         maxlen=nodestatus[si].mlen;
106     flag[si]=0;
107     return ml1+1;
108 }
109 
110 void dfs_2(int si)
111 {
112     int pno=nodestatus[si].pno;
113     int mlen=nodestatus[pno].minlen;
114     if(((nodestatus[pno].mlen>=maxlen)||(mlen<=1))&&(nodestatus[si].mslen==1))
115     {
116         nids.push_back(si);
117         return;
118     }
119     flag[si]=1;
120     int treeid=st[si];
121     if(nodestatus[pno].mlen>=maxlen)
122     {
123         if(nodestatus[si].mslen==nodestatus[pno].m1)
124         {
125             if(mlen>nodestatus[pno].m1) mlen=nodestatus[pno].m1;
126         }
127         else
128         {
129             if(mlen>nodestatus[pno].m2) mlen=nodestatus[pno].m2;
130         }
131     }
132     --mlen;
133     nodestatus[si].minlen=mlen;
134     while(treeid!=0)
135     {
136         int b=tree[treeid].to;
137         if(flag[b]==0)
138         {
139             dfs_2(b);
140         }
141         treeid=tree[treeid].next;
142     }
143     flag[si]=0;
144 }
145 
146 bool BFS(int ssi)
147 {
148     int level=1;
149     nodestatus[1].id=ssi;
150     int ind=1;
151     int i=1;
152     flag[ssi]=1;
153     while(i<=ind)
154     {
155         int si=nodestatus[i].id;
156         int treeid=st[si];
157         while(treeid!=0)
158         {
159             int b=tree[treeid].to;
160             if(flag[b]==0)
161             {
162                 ++ind;
163                 nodestatus[ind].id=b;
164                 nodestatus[ind].pno=i;
165                  flag[b]=1;
166             }
167             treeid=tree[treeid].next;
168         }
169         ++i;
170     }
171     return (ind<N);
172 }
173 
174 void BFS_1(int si)
175 {
176     for(int i=N;i>=1;--i)
177     {
178         nodestatus[i].mlen=nodestatus[i].m1+nodestatus[i].m2+1;
179         if(nodestatus[i].mlen>maxlen) maxlen=nodestatus[i].mlen;
180         nodestatus[i].mslen=nodestatus[i].m1+1;
181         int pno=nodestatus[i].pno;
182         if(nodestatus[pno].m1<=nodestatus[i].mslen)
183         {
184             nodestatus[pno].m2=nodestatus[pno].m1;
185             nodestatus[pno].m1=nodestatus[i].mslen;
186         }
187         else if(nodestatus[pno].m2<nodestatus[i].mslen)
188         {
189             nodestatus[pno].m2=nodestatus[i].mslen;
190         }
191     }
192 }
193 
194 void BFS_2(int si)
195 {
196     for(int i=1;i<=N;++i)
197     {
198         int pno=nodestatus[i].pno;
199         int mlen=nodestatus[pno].minlen;
200         if(((nodestatus[pno].mlen>=maxlen)||(mlen<=1))&&(nodestatus[i].mslen==1))
201         {
202             nids.push_back(nodestatus[i].id);
203         }
204         else
205         {
206             if(nodestatus[pno].mlen>=maxlen)
207             {
208                 if(nodestatus[i].mslen==nodestatus[pno].m1)
209                 {
210                     if(mlen>nodestatus[pno].m1) mlen=nodestatus[pno].m1;
211                 }
212                 else
213                 {
214                     if(mlen>nodestatus[pno].m2) mlen=nodestatus[pno].m2;
215                 }
216                 
217             }
218             --mlen;
219             nodestatus[i].minlen=mlen;
220         }
221     }
222 }
223 
224 int main()
225 {
226     scanf("%d",&N);
227     for(int i=1;i<N;++i)
228     {
229         int a,b;
230         scanf("%d %d",&a,&b);
231         addToTree(a,b);
232         addToTree(b,a);
233     }
234     int connect=0;
235     bool huan=false;
236     for(int i=1;i<=N;++i)
237     {
238         if(flag[i]==0)
239         {
240           if(dfs(i)<N)  huan=true;//if(BFS(i)<N)  huan=true;
241           ++connect;
242         }
243     }
244     if((connect>1)||(huan))
245     {
246         printf("Error: %d components\n",connect);
247     }
248     else
249     {
250         memset(flag,0,sizeof(flag));
251         if(N==1)
252             printf("1\n");
253         else
254         {
255             nodestatus[0].minlen=1000000;
256             dfs_1(1);//BFS_1(1);
257             dfs_2(1);//BFS_2(1);
258             sort(nids.begin(),nids.end(),cmp);
259             if((nodestatus[1].mslen>=maxlen)&&(nids[0]!=1))
260             {
261                 printf("1\n");
262             }
263             for(int i=0;i<nids.size();++i)
264             {
265                 printf("%d\n",nids[i]);
266             }
267         }
268     }
269     return 0;
270 }