算法: 树的直径

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("\n");
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)\n", u, v);
70 
71     return 0;
72 }

 

 

posted @ 2014-06-15 22:00  william-cheung  阅读(924)  评论(0编辑  收藏  举报