Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 906 Accepted Submission(s): 268
题意:给出一颗树(n个顶点,n-1条边)
求最长的路径,以及最长路径的条数。
路径无非就是连接两个点直接的路。
因为是一颗树,所以连接两个点肯定是唯一的路径。
其实就是求两点间距离的最大值,以及这个最大值有多少个。
首先统计出结点到叶子结点的最长距离和次长距离。
然后找寻经过这个点的,在这个为根结点的子树中的最长路径个数目。
...思路参考于kuangbin博客
代码:
1 #include "stdio.h" //poj 3534 Tree 树形dp 2 #include "string.h" 3 4 #define N 100100 5 6 struct node 7 { 8 int x,y; 9 int weight; 10 int next; 11 }edge[2*N]; 12 int idx,head[N]; 13 14 void Init() 15 { 16 idx = 0; 17 memset(head,-1,sizeof(head)); 18 } 19 20 void Add(int x,int y,int weight) 21 { 22 edge[idx].x = x; 23 edge[idx].y = y; 24 edge[idx].weight = weight; 25 edge[idx].next = head[x]; 26 head[x] = idx++; 27 } 28 29 int maxn[N]; //最长距离 30 int smaxn[N];//次长距离 31 int maxn_num[N]; //最长距离数目 32 int smaxn_num[N]; //次长距离数目 33 int path[N]; //经过点i的最长距离长度 34 int num[N]; //经过点i的最长距离数目 35 36 void DFS(int x,int father) 37 { 38 int i,y; 39 maxn[x] = smaxn[x] = 0; 40 maxn_num[x] = smaxn_num[x] = 0; 41 for(i=head[x]; i!=-1; i=edge[i].next) 42 { 43 y = edge[i].y; 44 if(y==father) continue; 45 DFS(y,x); 46 if(maxn[x] < maxn[y]+edge[i].weight) 47 { 48 smaxn[x] = maxn[x]; 49 smaxn_num[x] = maxn_num[x]; 50 maxn[x] = maxn[y]+edge[i].weight; 51 maxn_num[x] = maxn_num[y]; 52 } 53 else if(maxn[x]==maxn[y]+edge[i].weight) 54 maxn_num[x] += maxn_num[y]; 55 else if(smaxn[x] < maxn[y]+edge[i].weight) 56 { 57 smaxn[x] = maxn[y]+edge[i].weight; 58 smaxn_num[x] = maxn_num[y]; 59 } 60 else if(smaxn[x] == maxn[y]+edge[i].weight) 61 smaxn_num[x] += maxn_num[y]; 62 } 63 if(maxn_num[x]==0) //叶子节点,赋初值 64 { 65 maxn[x] = smaxn[x] = 0; 66 maxn_num[x] = smaxn_num[x] = 1; 67 path[x] = 0; 68 num[x] = 1; 69 return ; 70 } 71 int c1; //统计以x为根节点的最长距离数目 72 int c2; //统计以x为根节点的次长距离数目 73 c1 = c2 = 0; 74 for(i=head[x]; i!=-1; i=edge[i].next) 75 { 76 y=edge[i].y; 77 if(y==father) continue; 78 if(maxn[x] == maxn[y]+edge[i].weight) 79 c1++; 80 else if(smaxn[x] == maxn[y]+edge[i].weight) 81 c2++; 82 } 83 path[x] = 0; 84 num[x] = 0; 85 if(c1>=2) 86 { 87 int tmp = 0; 88 path[x] = maxn[x]*2; 89 for(i=head[x]; i!=-1; i=edge[i].next) 90 { 91 y = edge[i].y; 92 if(y==father) continue; 93 if(maxn[x]==maxn[y]+edge[i].weight) 94 { 95 num[x] += tmp*maxn_num[y]; 96 tmp += maxn_num[y]; 97 } 98 } 99 } 100 else if(c1>=1 && c2>=1) 101 { 102 path[x] = maxn[x]+smaxn[x]; 103 for(i=head[x]; i!=-1; i=edge[i].next) 104 { 105 y = edge[i].y; 106 if(y==father) continue; 107 if(maxn[x]==maxn[y]+edge[i].weight) 108 { 109 num[x] = smaxn_num[x]*maxn_num[y]; 110 } 111 } 112 } 113 else 114 { 115 path[x] = maxn[x]; 116 num[x] = maxn_num[x]; 117 } 118 } 119 120 int main() 121 { 122 int n; 123 int i,j; 124 int x,y,k; 125 while(scanf("%d",&n)!=EOF) 126 { 127 Init(); 128 for(i=1; i<n; ++i) 129 { 130 scanf("%d %d %d",&x,&y,&k); 131 Add(x,y,k); 132 Add(y,x,k); 133 } 134 DFS(1,-1); 135 int dist=0,snum=0; 136 for(i=1; i<=n; ++i) 137 { 138 if(path[i]>dist) 139 { 140 dist = path[i]; 141 snum = num[i]; 142 } 143 else if(path[i]==dist) 144 { 145 snum += num[i]; 146 } 147 } 148 printf("%d %d\n",dist,snum); 149 } 150 return 0; 151 }