题意:给定一棵树,求出树的直径以及个数。
思路:dfs到结点u时,顺便统计出以u为lca的路径的最长距离和个数。故需要求出每个结点到叶子结点的最长距离以及个数。题目居然不给数据范围,不过实测n最大值为10000。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 10001; 7 int head[N]; 8 int len[N]; 9 int num[N]; 10 int n, e, ans, cnt; 11 12 void init() 13 { 14 e = 0; 15 ans = 0; 16 cnt = 1; 17 memset( head, -1, sizeof(head) ); 18 } 19 20 struct Edge 21 { 22 int v, next, w; 23 } edge[N << 1]; 24 25 void addEdge( int u, int v, int w ) 26 { 27 edge[e].v = v; 28 edge[e].w = w; 29 edge[e].next = head[u]; 30 head[u] = e++; 31 } 32 33 void dfs( int u, int fa ) 34 { 35 len[u] = 0; 36 num[u] = 1; 37 for ( int i = head[u]; i != -1; i = edge[i].next ) 38 { 39 int v = edge[i].v, w = edge[i].w; 40 if ( v == fa ) continue; 41 dfs( v, u ); 42 if ( len[u] + len[v] + w > ans ) 43 { 44 ans = len[u] + len[v] + w; 45 cnt = num[u] * num[v]; 46 } 47 else if ( len[u] + len[v] + w == ans ) 48 { 49 cnt += num[u] * num[v]; 50 } 51 if ( len[v] + w > len[u] ) 52 { 53 len[u] = len[v] + w; 54 num[u] = num[v]; 55 } 56 else if ( len[v] + w == len[u] ) 57 { 58 num[u] += num[v]; 59 } 60 } 61 } 62 63 int main () 64 { 65 while ( scanf("%d", &n) != EOF ) 66 { 67 init(); 68 for ( int i = 1; i < n; i++ ) 69 { 70 int u, v, w; 71 scanf("%d%d%d", &u, &v, &w); 72 addEdge( u, v, w ); 73 addEdge( v, u, w ); 74 } 75 dfs( 1, -1 ); 76 printf("%d %d\n", ans, cnt); 77 } 78 return 0; 79 }