PAT 1021. Deepest Root (25)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT 1021. Deepest Root (25)相关的知识,希望对你有一定的参考价值。
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 }
以上是关于PAT 1021. Deepest Root (25)的主要内容,如果未能解决你的问题,请参考以下文章
PAT (Advanced Level) 1021. Deepest Root (25)