您的位置:首页 > 其它

大臣的旅费(求树的最远点对,即树的直径)

2016-03-16 14:48 260 查看
题目大意:求树上两点的最远距离。

分析:可以用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: