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 5Sample Output 1:
3 4 5Sample Input 2:
5 1 3 1 4 2 5 3 4Sample Output 2:
Error: 2 components
首先说说算法的思路:先用并查集判断树是否是联通;然后任选一个结点做bfs,则得到最低层的叶结点一定是Deepest Root,接下去在从已选出的Deepest Root中任选一点,在做一次dfs,然后在
将最底层的叶结点加入Deepest Root。此题在时间和空间上都有限制,如果暴力解决的话会超时,如果用邻接矩阵存树的话会超内存,所以采用链表存树。
代码
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 #define NUM 10001 6 typedef struct linkNode{ 7 int a; 8 linkNode *next; 9 }linkNode; 10 11 linkNode *map[NUM]; 12 int unionSet[NUM]; 13 int level[NUM]; 14 int queue[NUM]; 15 int deepestRoot[NUM]; 16 17 int findRoot(int); 18 int bfs(int); 19 void destroyMap(int); 20 21 int main() 22 { 23 int N,i; 24 int s,e; 25 int k; 26 linkNode *p; 27 while(scanf("%d",&N) != EOF){ 28 memset(unionSet,0,sizeof(unionSet)); 29 memset(map,0,sizeof(map)); 30 k = 0; 31 for(i=1;i<N;++i){ 32 scanf("%d%d",&s,&e); 33 int sR = findRoot(s); 34 int eR = findRoot(e); 35 if(sR != eR){ 36 unionSet[sR] = eR; 37 ++k; 38 p = (linkNode*) malloc(sizeof(linkNode)); 39 p->a = e; 40 p->next = NULL; 41 if(map[s]){ 42 p->next = map[s]; 43 map[s] = p; 44 } 45 else 46 map[s] = p; 47 p = (linkNode*) malloc(sizeof(linkNode)); 48 p->a = s; 49 p->next = NULL; 50 if(map[e]){ 51 p->next = map[e]; 52 map[e] = p; 53 } 54 else 55 map[e] = p; 56 } 57 } 58 if(k < N - 1){ 59 printf("Error: %d components ",N-k); 60 destroyMap(N); 61 continue; 62 } 63 memset(deepestRoot,0,sizeof(deepestRoot)); 64 int maxLevel = bfs(1); 65 int maxLevel_i; 66 for(i=1;i<=N;++i){ 67 if(level[i] == maxLevel){ 68 deepestRoot[i] = 1; 69 maxLevel_i = i; 70 } 71 } 72 maxLevel = bfs(maxLevel_i); 73 for(i=1;i<=N;++i){ 74 if(level[i] == maxLevel) 75 deepestRoot[i] = 1; 76 } 77 for(i=1;i<=N;++i){ 78 if(deepestRoot[i]) 79 printf("%d ",i); 80 } 81 destroyMap(N); 82 } 83 return 0; 84 } 85 86 int findRoot(int s) 87 { 88 while(unionSet[s]) 89 s = unionSet[s]; 90 return s; 91 } 92 93 94 int bfs(int s) 95 { 96 memset(level,-1,sizeof(level)); 97 int base = 0,top = 0; 98 int levelNum = 1,endLevel = 1; 99 int t,i; 100 linkNode *p; 101 queue[top++] = s; 102 while(top > base){ 103 t = queue[base++]; 104 level[t] = levelNum; 105 p = map[t]; 106 while(p){ 107 if(level[p->a] == -1){ 108 queue[top++] = p->a; 109 } 110 p = p->next; 111 } 112 if(endLevel == base){ 113 endLevel = top; 114 ++levelNum; 115 } 116 } 117 return levelNum - 1; 118 } 119 120 void destroyMap(int n) 121 { 122 linkNode *p,*q; 123 int i; 124 for(i=1;i<=n;++i){ 125 p = map[i]; 126 while(p){ 127 q = p->next; 128 free(p); 129 p = q; 130 } 131 } 132 }