您的位置:首页 > Web前端 > Node.js

LightOJ 1094 - Farthest Nodes in a Tree

2015-08-18 19:08 686 查看
http://lightoj.com/volume_showproblem.php?problem=1094

树的直径是指树的最长简单路。

求法: 两遍BFS :先任选一个起点BFS找到最长路的终点,再从终点进行BFS,则第二次BFS找到的最长路即为树的直径;

原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点

证明:

1) 如果u 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点w使得u到w的距离更长,则于BFS找到了v矛盾)
2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了
所以v一定是直径的一个端点,所以从v进行BFS得到的一定是直径长度

详细证明请参考:

/article/5031377.html

#include <cstdio>
#include <cstring>
#include <ostream>
#include <algorithm>

using namespace std;

#define N 30010

struct Edge
{
int u, v, next, l;
}edge[N * 4];

int head
, dist
, Max, cnt, Index;

void Init()
{
memset(head, -1, sizeof(head));
cnt = 0;
}

void AddEdge(int u, int v, int l)
{
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].l = l;
edge[cnt].next = head[u];
head[u] = cnt++;
}

void DFS(int u, int l)
{
int v, i;
dist[u] = l;
if(dist[u] > Max)
{
Max = dist[u];
Index = u;
}
for(i = head[u] ; i != -1 ; i = edge[i].next)
{
v = edge[i].v;
if(dist[v] == -1)
DFS(v, edge[i].l + dist[u]);
}
}

int main()
{
int t, n, u, v, l, i, x = 0;
scanf("%d", &t);
while(t--)
{
x++;
Init();
scanf("%d", &n);
for(i = 1 ; i < n ; i++)
{
scanf("%d%d%d", &u, &v, &l);
AddEdge(u, v, l);
AddEdge(v, u, l);
}
Max = 0;
memset(dist, -1, sizeof(dist));
DFS(0, 0);//以树中任意一个结点为源点(这里暂且选0当源点),进行一次广度优先遍历,找出离源点距离最远的点Index
memset(dist, -1, sizeof(dist));
DFS(Index, 0);//以Index为源点,进行一次广度优先遍历,找出离Index最远的点,并记录其长度,该长度即为树的直径
printf("Case %d: %d\n", x, Max);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: