Hdu2196 Computer

Computer

HDU - 2196

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.

InputInput 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.OutputFor 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


/*
    树形dp,方程好像不明显
    不难发现,从每个点出发的最长链有两种可能,一种是贯穿他的子树,另一种是从他的父亲节点穿出去
    可以用两个dfs,第一个不考虑其父亲节点的情况,只得出其贯穿子树的最长链
    第二个dfs,将父亲节点考虑上,比一比怎样更优
    所以我们应该维护两个值,最大和次大,以满足考虑父亲节点时的工作。
    如果这个点在从父亲结点出发的最长链上时就考虑他与父亲相连的那条边加上他父亲连出去的次长链能否对其更新
    否则,就用他与父亲相连的那条边加上他父亲连出去的最长链更新
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 10010
int mx1[maxn],mx2[maxn],mx1id[maxn],mx2id[maxn],head[maxn*2];
int n,num;
struct node{
    int to,v,pre;
}e[maxn*2];
void Insert(int from,int to,int v){
    e[++num].to=to;e[num].v=v;
    e[num].pre=head[from];head[from]=num;

    e[++num].to=from;e[num].v=v;
    e[num].pre=head[to];head[to]=num;
}
void dfs1(int fa,int u){
    for(int i=head[u];i;i=e[i].pre){
        int v=e[i].to;
        if(v==fa)continue;
        dfs1(u,v);
        if(mx2[u]<mx1[v]+e[i].v){
            mx2[u]=mx1[v]+e[i].v;
            mx2id[u]=v;
            if(mx2[u]>mx1[u]){
                swap(mx2[u],mx1[u]);
                swap(mx2id[u],mx1id[u]);
            }
        }
    }
}
void dfs2(int fa,int u){
    for(int i=head[u];i;i=e[i].pre){
        int v=e[i].to;
        if(v==fa)continue;
        if(v==mx1id[u]){
            if(mx2[v]<mx2[u]+e[i].v){
                mx2[v]=mx2[u]+e[i].v;
                mx2id[v]=u;
                if(mx2[v]>mx1[v]){
                    swap(mx2[v],mx1[v]);
                    swap(mx2id[v],mx1id[v]);
                }
            }
        }
        else if(mx2[v]<mx1[u]+e[i].v){
            mx2[v]=mx1[u]+e[i].v;
            mx2id[v]=u;
            if(mx2[v]>mx1[v]){
                swap(mx2[v],mx1[v]);
                swap(mx2id[v],mx1id[v]);
            }
        }
        dfs2(u,v);
    }
}
int main(){
    freopen("Cola.txt","r",stdin);
    int x,y;
    while(scanf("%d",&n)!=EOF){
        memset(head,0,sizeof(head));num=0;
        memset(mx1,0,sizeof(mx1));memset(mx2,0,sizeof(mx2));
        memset(mx1id,0,sizeof(mx1id));memset(mx2id,0,sizeof(mx2id));
        for(int i=2;i<=n;i++){
            scanf("%d%d",&x,&y);
            Insert(i,x,y);
        }
        dfs1(-1,1);
        dfs2(-1,1);
        for(int i=1;i<=n;i++){
            printf("%d\n",mx1[i]);
        }
    }
}

 
				
时间: 2024-10-12 19:06:12

Hdu2196 Computer的相关文章

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). D

HDU-2196 Computer (树形DP)

最近在看树形DP,这题应该是树形DP的经典题了,写完以后还是有点感觉的.之后看了discuss可以用树分治来做,以后再试一试. 题目大意 找到带权树上离每个点的最远点.︿( ̄︶ ̄)︿ 题解: 对于每一个点的最远点,就是以这个点为根到所有叶子节点的最长距离.但是如果确定根的话,除了根节点外,只能找到每个节点(度数-1)个子树的最大值,剩下一个子树是该节点当前的父亲节点. 所以当前节点的最远点在当前节点子树的所有叶子节点以及父亲节点的最远点上(当父亲节点的最远点不在当前节点的子树上时), 如果父亲节

HDU2196 Computer(树形DP)

和LightOJ1257一样,之前我用了树分治写了.其实原来这题是道经典的树形DP,感觉这个DP不简单.. dp[0][u]表示以u为根的子树中的结点与u的最远距离 dp[1][u]表示以u为根的子树中的结点与u的次远距离 这两个可以一遍dfs通过儿子结点转移得到.显然dp[0][u]就是u的一个可能的答案,即u往下走的最远距离,还缺一部分就是u往上走的最远距离: dp[2][u]表示u往上走的最远距离 对于这个的转移,分两种情况,是这样的: dp[2][v] = max( dp[0][u]+w

[HDU2196]Computer(DP)

传送门 题意 给出一棵树,求离每个节点最远的点的距离 思路 对于我这种菜鸡,真是难啊. 我们能够很简单的求出每个点到以它为根的子树的最远点的距离,dfs 即可. 设 f[i][0] 表示点 i 到以它为根的子树的最远点的距离 f[i][1] 表示点 i 到以它为根的子树的次远点的距离(一会会用到) f[i][2] 表示 除去点 i 的子树后,点 i 到离它最远的点的距离  val 表示边权 那么 f[v][2] 怎么求?(u 表示 v 的父亲) if(f[v][0] + val[i] == f[

HDU-2196 Computer (树形DP)

题目大意:在一棵带边权的有根树中,对于每个点,找出它与离它最远的那个点的之间的距离. 题目分析:对于一个点,离它最远的点只有两种情况,一是它到叶子节点的最远距离,一是与它父亲的距离加上他的父亲到叶子节点的最远距离.因为它的父亲到叶子的最远距离的那条路径可能恰好经过它自己,所以还要求出每个点到叶子节点的次大距离. 代码如下: # include<iostream> # include<cstdio> # include<vector> # include<cstri

hdu2196 Computer(树上最长路径 dp)

题目链接:点击打开链接 题意描述:给定一棵树,树上每条边的有一个权值,问从任意一个点出发能走得最长路径是多少? 解题思路:树上最长路径 dp 1.任意找一个点作为根节点,将无根树转化为有根树 2.在dfs过程中更新f[i],g[i],其中f[i]记录以i为节点向下扩展最长路,g[i]为次长路,并用mark标记每个节点最长路的儿子节点 3.在dfs1的过程中更新h[i],h[i]表示以i为节点的向上扩展的最长路 代码: #pragma comment(linker,"/STACK:10240000

【树形dp小练】HDU1520 HDU2196 HDU1561 HDU3534

[树形dp]就是在树上做的一些dp之类的递推,因为一般需要递归处理,因此平凡情况的处理可能需要理清思路.昨晚开始切了4题,作为入门训练.题目都非常简单,但是似乎做起来都还口以- hdu1520 Anniversary party 给一颗关系树,各点有权值,选一些点出来.任一对直接相连的边连接的点不能同时选择,问选择出的权值和最大为多少. 考虑以u为根的子树可以选择的方法,dp[u]表示选择u时能获得最大收益,dp2[u]表示不选u时能获得的最大收益.则u不选时,为dp2[u]=max{dp[v]

DP Intro - Tree DP Examples

因为上次比赛sb地把一道树形dp当费用流做了,受了点刺激,用一天时间稍微搞一下树形DP,今后再好好搞一下) 基于背包原理的树形DP poj 1947 Rebuilding Roads 题意:给你一棵树,让你求最少剪掉多少条边可以剪出一棵点数为m的子树. 解法:dp[i][j]表示i节点得到j个节点的子树至少要剪多少边,对于每个节点a和它的孩子b,如果剪掉b,则dp(s)[a][j]=dp(s-1)[a][j], 如果保留<a,b>dp(s)[a][j]=min{dp(s-1)[a][j - k

今日份水题2018.11.2

这几天想突破一下树形DP,这也是高中时候一直没能搞定的. 今天先来两道简单的水一下. HDU2196 Computer 给一棵树,求树中每个点离其他点最远的距离.每个点第一遍DFS记录能达到的最远距离dp1[]和次远距离dp2[],之后第二遍dfs,每次先更新当前节点答案然后再向下搜.如果当前节点位于父节点答案所在链上,即dp1[j]+w[i,j]=dp1[i],此时又分两种情况1: dp1[j]<dp2[i]+w[i,j],则dp2[j]=dp1[j],dp1[j]=dp2[i]+w[i,j]