Computer

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5194    Accepted Submission(s): 2620

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
题意:求树上每个点到离它最远的点的距离.(方法一难懂,方法二我也不知道为什么是正确的,没办法证明)
方法一:
分析:要求树上每个点能够到达的最远距离,那么最远距离这个值有两个来源,分别是来自其子树或者来自其父亲,我们先用一次深搜将每棵树的子树遍历,求出子树的最大值和次
大值并且两个值所在的分支不同,为什么需要求出次大值呢?这里就是本题的精华了:在第二次DFS时,如果父亲在子树能够到达的最远距离和当前要求解的子结点在同一条分支上,那么我们就肯定不能选这条了,而应该选其"兄弟"结点中的最长路,也就是次短路.(这一点需要画图好好理解)
dp[i][0]代表以i为根子树中的最长路,dp[i][1]代表子树中的次长路,dp[i][2]代表父亲树中的最长路,设i的父亲为fi
dp[i][2] = max(dp[fi][2] , dp[i][0]+dis[i][fi]==dp[fi][0]?dp[fi][1]:dp[fi][0]) + dis[i][fi];
///题意:求树上每个点到离它最远的点的距离.
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 10050
using namespace std; struct Edge{
int u,v,w,next;
}edge[*N];
int head[N];
int dp[N][]; ///dp[i][0]代表以i为根子树中的最长路,dp[i][1]代表子树中的次长路,dp[i][2]代表父亲树中的最长路 void addEdge(int u,int v,int w,int &k){
edge[k].u = u,edge[k].v = v,edge[k].w = w;
edge[k].next = head[u],head[u]=k++;
} void dfs(int u,int fa){ ///找子树中的最大值和次大值
for(int k = head[u];k!=-;k=edge[k].next){
int v = edge[k].v;
if(v==fa) continue;
//printf("%d\n",v);
dfs(v,u);
if(dp[u][]<dp[v][]+edge[k].w){
dp[u][] = dp[v][] + edge[k].w;
if(dp[u][]>dp[u][]){
swap(dp[u][],dp[u][]);
}
}
}
}
void dfs1(int u,int fa){///找从父亲延伸过去的最大值
for(int k = head[u];k!=-;k=edge[k].next){
int v = edge[k].v,w = edge[k].w;
if(v==fa) continue;
dp[v][] = max(dp[u][] , dp[v][]+edge[k].w==dp[u][]?dp[u][]:dp[u][]) + edge[k].w;
dfs1(v,u);
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(head,-,sizeof(head));
memset(dp,,sizeof(dp));
int tot=;
for(int u=;u<=n;u++){
int v,w;
scanf("%d%d",&v,&w);
addEdge(u,v,w,tot);
addEdge(v,u,w,tot);
}
dfs(,-);
dfs1(,-);
for(int i=;i<=n;i++){
printf("%d\n",max(dp[i][],dp[i][]));
}
}
return ;
}

方法二:先对任意一个点进行搜索的到离它最远的端点,这个点必定是树的直径(树的直径指树中的最长路)的其中一个端点,然后以这个端点开始又进行搜索,得到一个离他最远

的店,这个点是直径的另外一个端点,我们在找的时候分别更新所有点到两个端点的距离,对于每个点我们区大值就是结果。

///题意:求树上每个点到离它最远的点的距离.
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#define N 10050
using namespace std; struct Edge{
int u,v,w,next;
}edge[*N];
int head[N]; void addEdge(int u,int v,int w,int &k){
edge[k].u = u,edge[k].v = v,edge[k].w = w;
edge[k].next = head[u],head[u]=k++;
}
int dis[N],dis1[N];
int vis[N];
void BFS(int x){
memset(vis,,sizeof(vis));
queue<int> q;
q.push(x);
vis[x]=;
while(!q.empty()){
int t = q.front();
q.pop();
for(int k=head[t];k!=-;k=edge[k].next){
int v = edge[k].v,w=edge[k].w;
if(!vis[v]){
vis[v]=;
q.push(v);
dis[v] =max(dis[v],dis[t]+w);
}
}
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(head,-,sizeof(head));
memset(dis,,sizeof(dis));
memset(dis1,,sizeof(dis1));
int tot=;
for(int u=;u<=n;u++){
int v,w;
scanf("%d%d",&v,&w);
addEdge(u,v,w,tot);
addEdge(v,u,w,tot);
}
BFS();
int START=,END=;
int len = -;
for(int i=;i<=n;i++) {
if(dis[i]>len) {len = dis[i],START = i;}
}
memset(dis,,sizeof(dis));
BFS(START);
len = -;
for(int i=;i<=n;i++) {
dis1[i]=dis[i];
if(dis[i]>len) {len = dis[i],END = i;}
}
memset(dis,,sizeof(dis));
BFS(END);
for(int i=;i<=n;i++){
printf("%d\n",max(dis[i],dis1[i]));
} }
return ;
}

hdu 2196(方法1:经典树形DP+方法2:树的直径)的更多相关文章

  1. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  2. HDU 4616 Game(经典树形dp+最大权值和链)

    http://acm.hdu.edu.cn/showproblem.php?pid=4616 题意:给出一棵树,每个顶点有权值,还有存在陷阱,现在从任意一个顶点出发,并且每个顶点只能经过一次,如果经过 ...

  3. hdu 1054 Strategic Game 经典树形DP

    Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  4. hdoj3534(树形dp,求树的直径的条数)

    题目链接:https://vjudge.net/problem/HDU-3534 题意:给出一棵树,求树上最长距离(直径),以及这样的距离的条数. 思路:如果只求直径,用两次dfs即可.但是现在要求最 ...

  5. hdu 4514 并查集+树形dp

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  6. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  7. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  8. HDU 1561 The more, The Better 经典树形DP

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  9. HDU 3534 Tree (经典树形dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3534 题意: 给你一棵树,问你有多少对点的距离等于树的直径. 思路: dp[i][0]表示在i的子树中 ...

随机推荐

  1. Extjs的API阅读方式(整理)

    原文链接:http://www.cnblogs.com/gaojun/archive/2013/05/28/3103908.html

  2. float与定位的区别

    float和绝对定位的区别 CSS中脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当做脱离文档流的元素不存在而进行定位.1 需要注意的是,使用float脱离文档流时,其他盒子 ...

  3. iOS进阶--提高XCode编译速度、Xcode卡顿解决方案

    提升编译链接的速度主要有以下三个方式: 1. 提高XCode编译时使用的线程数 defaults write com.apple.Xcode PBXNumberOfParallelBuildSubta ...

  4. [bzoj4071] [Apio2015]巴邻旁之桥

    Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...

  5. CTSC2018 & APIO2018 颓废 + 打铁记

    CTSC2018 & APIO2018 颓废 + 打铁记 CTSC 5 月 6 日 完美错过报道,到酒店领了房卡放完行李后直接奔向八十中拿胸牌.饭票和资料.试机时是九省联考的题,从来没做过,我 ...

  6. HDU 5665

    Lucky Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  7. 封装安卓的okhttp

    1.封装了get方法,handler更新主线程,回调的onsuccess,onfailure,onerror等方法 2.配置文件 api 'com.android.support:recyclervi ...

  8. lwIP内存管理机制

    lwip的内存管理机制,我们以enet_lwip这个例程为例. 在使用lwip的时候,我们可以使用两种形式的内存,一种是heap(mem.c文件-mem_malloc()),一种是pool(memp. ...

  9. 7月19日day11总结

    今天学习过程和小结 上午进行测试复习了 1,hdfs中namenode和datanode作用 2,hdfs副本存放机制 3,mapreduce计算处理过程 4,格式化hdfs命令 5,hdfs的核心配 ...

  10. 一些常用的css片段

    1. 单行文字溢出时省略号 .test{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } 2. 多行文字溢出时省略号 .t ...