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 }