hdu2196 Computer(树的直径||树中的最长路径)

Computer

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 5232    Accepted Submission(s): 2640

Problem Description

A school bought the first computer some time ago(so this computer‘s id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about
slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.

Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also
get S4 = 4, S5 = 4.

Input

Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which
i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.

Output

For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).

Sample Input

5
1 1
2 1
3 1
1 1

Sample Output

3
2
3
4
4

Author

scnu

Recommend

lcy   |   We have carefully selected several similar problems for you:  1561 1011 3456 1520 2242

Statistic | Submit | Discuss
| Note

若想做这道题 首先要懂得树的最长路怎么计算

首先假设树的最长路的两个叶子节点为v1,v2,那么现有结论,从任意一点u出发走到的最远的点一定是(v1,v2)中的一点,然后

再从v1或者v2出发走到的最远点一定是v2或者v1。所以经过两次搜索就能找到最长路径。

这里有证明:

假设 s-t这条路径为树的直径,或者称为树上的最长路

现有结论,从任意一点u出发搜到的最远的点一定是s、t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜就可以找出树的最长路

证明:

1    设u为s-t路径上的一点,结论显然成立,否则设搜到的最远点为T则

dis(u,T) >dis(u,s)     且  dis(u,T)>dis(u,t)   则最长路不是s-t了,与假设矛盾

2   设u不为s-t路径上的点

首先明确,假如u走到了s-t路径上的一点,那么接下来的路径肯定都在s-t上了,而且终点为s或t,在1中已经证明过了

所以现在又有两种情况了:

1:u走到了s-t路径上的某点,假设为X,最后肯定走到某个端点,假设是t ,则路径总长度为dis(u,X)+dis(X,t)

2:u走到最远点的路径u-T与s-t无交点,则dis(u-T) >dis(u,X)+dis(X,t);显然,如果这个式子成立,

则dis(u,T)+dis(s,X)+dis(u,X)>dis(s,X)+dis(X,t)=dis(s,t)最长路不是s-t矛盾

证明转自 :http://www.cnblogs.com/wuyiqi/archive/2012/04/08/2437424.html

而这道题不是找最长路径,是找某个节点x所能到达的最长路径。首先这个节点x的最长路径要么是到v1的路径,要么就是到v2的路径。由于我们不知道从那边走才是最长的路径 所以需要分别从v1,v2点再次搜索 共需要三次搜索  在这里可能一些同学会说了两次搜索不行吗?我们在第一次搜索找到了v1,v2中的一个点 然后再从v1或者v2点搜索到另外一个点v2或者v1 搜索的过程中用dist[x]保存走过的路径长度  最后输出的时候通过比较当前的路径和最长路径减去到当前的路径
取最大值(max(dist[v]-dist[x],dist[x]))  其实我也是这一些同学的一份子 提交的时候Wa了  后来仔细分析了一下  这样是错误的 我们只能保证x走到的最远点有一点是v1,或者v2 却不能保证另外一点也是 所以不能这样减去。看看这个图

可以看到最长路径为7-》1-》4-》5-》6-》8   dist[7]=dist[8]=5

第一次从1搜索后得到dist[8]=5,dist[2]=3

如果根据这个公式(max(dist[8]-dist[2],dist[2]))=3  可是在图中我们可以明显看到dist[2]的最大值为2-》5-》4-》1-》7  长度为4

就说这么多吧 附上代码:

#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
int root,max_len;
int dist[10000+5];
struct Edge
{
    int pos;
    int cost;
    Edge(int a,int x)
    {
        pos=a;
        cost=x;
    }
};
vector<Edge>tree[10000+5];
void dfs(int u,int v,int len)
{
    if(max_len<len) max_len=len,root=u;
    for(int i=0;i<tree[u].size();i++)
    {
        int pos=tree[u][i].pos;
        int cost=tree[u][i].cost;
        if(v==pos) continue;
        dfs(pos,u,len+cost);
        dist[pos]=max(dist[pos],len+cost);
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int max_val=0;
        memset(tree,0,sizeof(tree));
        memset(dist,0,sizeof(dist));
        for(int i=2;i<=n;i++)
        {
            int a,x;
            scanf("%d %d",&a,&x);
            tree[i].push_back(Edge(a,x));
            tree[a].push_back(Edge(i,x));
        }
        max_len=0;
        dfs(1,-1,0);
        dfs(root,-1,0);
        dfs(root,-1,0);
        for(int i=1;i<=n;i++)
        printf("%d\n",dist[i]);
    }
    return 0;
} 
时间: 2024-09-30 06:58:08

hdu2196 Computer(树的直径||树中的最长路径)的相关文章

树中的最长路径

问题分析: 树中的路径,即是从树上的某个节点起,经过某个转折节点,到达另一个节点这样一条路径.而最长路径就是要找出这些路径中最长的那一条. 算法思路: 对于每个节点,记录下以该节点为根节点的子树中从该节点开始到所有叶子节点的路径中最长的那一条路径长度d1以及次长的那一条路径长度d2(最长和次长两条路径无公共边).那么对于我们想要解决的问题(树中的最长路径),就只需要枚举每个节点作为转折节点,求出所有d1+d2中的最大值. 关于d1,d2的求解: 对于任意一个节点,其d1值等于其所有子节点最大d1

hdu 2196 Computer 树的直径

Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers

HDOJ 2196 Computer 树的直径

由树的直径定义可得,树上任意一点到树的直径上的两个端点之一的距离是最长的... 三遍BFS求树的直径并预处理距离....... Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3522    Accepted Submission(s): 1784 Problem Description A school bought

&lt;学习笔记&gt; 树的直径 Bfs、Dfs

树的直径为树上最长的一条路径(不经过重复节点),也可以看做是树上最长路. 通常的求法: 1.两边Bfs或两边Dfs 2.树形dp(端点为根和仅经过根). emmm ..蒟蒻表示目前只会第一种QAQ. 从树中找出任意一点,求出与他距离最远的点s,再用同样的方法求出与s距离最远的点t,s-t即为树的直径. Bfs代码 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cma

[模拟赛10.12] 老大 (二分/树的直径/树形dp)

[模拟赛10.12] 老大 题目描述 因为 OB 今年拿下 4 块金牌,学校赞助扩建劳模办公室为劳模办公室群,为了体现 OI 的特色,办公室群被设计成了树形(n 个点 n ? 1 条边的无向连通图),由于新建的办公室太大以至于要将奖杯要分放在两个不同的地方以便同学们丢硬币进去开光,OB 想请你帮帮他看看奖杯放在哪两个办公室使得在任意一个在劳模办公室做题的小朋友能最快地找到奖杯来开光. 一句话题意:给出一个 n 个点的树,在两个合适且不同的点放上奖杯,使得每个点到最近的奖杯距离最大值最小. 输入

[树的直径]F. Three Paths on a Tree

F. Three Paths on a Tree Description You are given an unweighted tree with nn vertices. Recall that a tree is a connected undirected graph without cycles. Your task is to choose three distinct vertices a,b,ca,b,c on this tree such that the number of

在二进制树中的节点之间的最大距离(最长路径树)——递归解决方案

上一篇文章即是对这一主题的变化.并给出了一个非递归溶液. 我给出原题的一种递归解法. 将会看到,现比較上篇博文.今天给出的递归解法的代码实现是相当简洁的. 问题描写叙述: 假设我们把二叉树看成一个图.父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数. 写一个程序.求一棵二叉树中相距最远的两个节点之间的距离.測试用的树: n1 /             \ n2             n3 /        \ n4          n5 /     \  

二叉树中节点的最大距离(树的最长路径)——递归解法

上一篇文章说的是该题的一种变形,并给出了非递归解法. 现在我给出原题的一种递归解法.将会看到,现比较上篇博文,今天给出的递归解法的代码实现是相当简洁的. 问题描述: 如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数. 写一个程序,求一棵二叉树中相距最远的两个节点之间的距离.测试用的树: n1 /             \ n2             n3 /        \ n4          n5 /     \    

变形二叉树中节点的最大距离(树的最长路径)——非递归解法

问题描述: 如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数. 写一个程序,求一棵二叉树中相距最远的两个节点之间的距离.测试用的树: n1 /             \ n2             n3 /        \ n4          n5 /     \         /   \ n6    n7    n8    n9 /                       / n10