題目大意:求樹上兩點的最遠距離。
分析:可以用DP解,也可以用兩次DFS。這裏我用兩次DFS,樹上最遠的點對一定是樹的直徑,而且樹上其他點到樹的直徑某一端點肯定是最遠的,第一遍搜找到直徑的某個端點,第二次就可以找出來樹的直徑了,然後就找到了最遠的點對啦。關鍵在於,理解樹上任意一點搜一次的最遠點一定在直徑的某個端點上。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100000;
struct node{
int next;
int to;
int w;
}edge[maxn];
int n, cnt, x, maxx;
int head[maxn];
bool vis[maxn];
void dfs(int a, int sum) {
if(maxx < sum) {
maxx = sum;
x = a;
}
for(int i = head[a]; ~i; i = edge[i].next) {
int t = edge[i].to;
if(!vis[t]) {
vis[t] = true;
dfs(t, sum+edge[i].w);
vis[t] = false;
}
}
}
int main() {
while(~scanf("%d", &n)) {
memset(head, -1, sizeof(head));
for(int i = 0; i < n-1; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[i].to = b-1;
edge[i].next = head[a-1];
edge[i].w = c;
head[a-1] = i;
edge[n-1+i].to = a-1;
edge[n-1+i].next = head[b-1];
edge[n-1+i].w = c;
head[b-1] = n-1+i;
}
x = maxx = 0;
memset(vis, 0, sizeof(vis));
vis[0] = true;
dfs(0, 0);
vis[0] = false;
memset(vis, 0, sizeof(vis));
vis[x] = true;
dfs(x, 0);
printf("%d\n", maxx*(11+10+maxx)/2);
}
return 0;
}