1. 二叉树的直径
1 int height(Node* root) { // 二叉树的高度 2 int ret = 0; 3 if (root != null) { 4 ret = 1 + max(height(root->left), height(root->right)); 5 } 6 return ret; 7 } 8 9 int diameter(Node* root) { 10 int ret = 0; 11 if (root != null) { 12 int lefth = height(root->left); 13 int righth = height(root->right); 14 ret = max(lefth + 1 + righth, 15 diameter(root->left), 16 diameter(root->right)); 17 } 18 return ret; 19 }
2. 无向树的直径
A standard algorithm for finding longest path in undirected trees using two depth-first searches:
(1) Start DFS from a random vertex v and find the farthest vertex from it; say it is v′.
(2) Now start a DFS from v′ to find the vertex farthest from it. This path is the longest path in the graph.
算法要求树中边的权值非负。
这里有一个观察: 在树中, 与一个节点距离最远的节点, 一定是树的直径的端点。(尚不知如何证明。)
1 #include <stdio.h> 2 3 #define N (10 + 1) 4 #define M 2*N 5 6 typedef struct s_edge { 7 int v, w; 8 int next; 9 } Edge; 10 11 Edge edges[M]; int ne = 0; 12 int adj[N]; int nv; 13 int visited[N]; 14 15 int find_furthest(int u, int* pv) { // 求一个与 u 距离最远的节点, 并返回最远距离 16 int dist = 0; 17 int i, flag = 0; 18 visited[u] = 1; 19 for (i = adj[u]; i != -1; i = edges[i].next) { 20 int v = edges[i].v, x; 21 if (visited[v] == 0) { 22 int tmp = edges[i].w + find_furthest(v, &x); 23 if (tmp > dist) { 24 dist = tmp, *pv = x; 25 } 26 flag = 1; 27 } 28 } 29 if (flag == 0) *pv = u; 30 return dist; 31 } 32 33 int furthest_vertex(int u) { // 求一个与 u 距离最远的节点 34 int v; 35 memset(visited, 0, sizeof(visited)); 36 find_furthest(u, &v); 37 return v; 38 } 39 40 void print_graph() { // 打印图的邻接表 41 int u, i, v; 42 for (u = 1; u <= nv; u++) { 43 printf("%d : ", u); 44 for (i = adj[u]; i != -1; i = edges[i].next) { 45 printf("%d ", edges[i].v); 46 } 47 printf(" "); 48 } 49 } 50 51 int main() { 52 int i, u, v, w; 53 scanf("%d", &nv); // 输入节点数 54 for (i = 1; i <= nv; i++) { 55 adj[i] = -1; 56 } 57 for (i = 1; i < nv; i++) { 58 scanf("%d%d%d", &u, &v, &w); // 输入边, 端点u、v, 权值 w (w >= 0) 59 edges[ne].v = v, edges[ne].w = w; 60 edges[ne].next = adj[u], adj[u] = ne++; 61 edges[ne].v = u, edges[ne].w = w; 62 edges[ne].next = adj[v], adj[v] = ne++; 63 } 64 //print_graph(); 65 66 u = furthest_vertex(1); 67 v = furthest_vertex(u); 68 69 printf("(%d, %d) ", u, v); 70 71 return 0; 72 }