POJ 1849 树的直径 Two

如果一个点开始遍历一棵树再回到原点那么每条边走两次。

现在是两个人从同一点出发,那么最后遍历完以后两人离得越远越好。

最后两人所处位置的路径上的边走了一次,其他边走了两次。

要使总路程最小,两人最后停在直径两端。

所以最终答案就是总权值*2 - 树的直径

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 100000 + 10;
 9 
10 int n, s;
11 vector<int> G[maxn], C[maxn];
12 
13 int len, id;
14 
15 void dfs(int u, int fa, int d)
16 {
17     if(d > len) { len = d; id = u; }
18     for(int i = 0; i < G[u].size(); i++)
19     {
20         int v = G[u][i];
21         if(v == fa) continue;
22         dfs(v, u, d + C[u][i]);
23     }
24 }
25 
26 int main()
27 {
28     while(scanf("%d%d", &n, &s) == 2)
29     {
30         for(int i = 1; i <= n; i++) { G[i].clear(); C[i].clear(); }
31 
32         int sum = 0;
33         for(int i = 1; i < n; i++)
34         {
35             int u, v, d; scanf("%d%d%d", &u, &v, &d);
36             sum += d * 2;
37             G[u].push_back(v); C[u].push_back(d);
38             G[v].push_back(u); C[v].push_back(d);
39         }
40 
41         int a;
42         len = -1;
43         dfs(1, 0, 0);
44         len = -1;
45         a = id;
46         dfs(a, 0, 0);
47 
48         printf("%d\n", sum - len);
49     }
50 
51     return 0;
52 }
代码君

 

posted @ 2015-07-31 11:07  AOQNRMGYXLMV  阅读(204)  评论(0编辑  收藏  举报