树形DP求各点能走到的最远距离
Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2903 Accepted Submission(s): 1472
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.
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.
5
1 1
2 1
3 1
1 1
3
2
3
4
4
题意:
求一个树中所有节点能到达的最远距离f[i]。要用两个dfs。
分析:
首先第一个dfs求出所有每个节点i在其子树中的正向最大距离和正向次大距离和dist[i][0]和dist[i][1](如果i节点在子树中最大距离经过了2号儿子,那么次大距离就是不经过2号儿子的最大距离)。并且还要标记longest[i]=j表示节点i在其子树中的最大距离经过了节点j(即j是i的一个儿子)。
由上步我们获得了正向最大距离,正向次大距离和最大距离的儿子节点标记。画图可以知道我们建立的这棵树,i节点的最远距离只有两种选择:i节点所在子树的最大距离,或者i节点连接它的父节点所能到达的最大距离。(即前者往下走,后者先往上走之后很可能也往下走)
所以我们只要求出反向最大距离dist[i][2](即i节点往它的父节点走所能到达的最大距离)就可以知道i节点在整个树中能走的最大距离了。
dist[i][2]求法:i节点往它的父节j点走,如果它的父节点的正向最大距离不经过i的话,那么dist[i][2]要不就是它父节点的反向最大距离+W[i][j]要不就是它父节点的正向最大距离+
W[i][j].
如果它的父节点的正向最大距离经过i的话,那么dist[i][2]要不就是它父节点的反向最大距离+W[i][j]要不就是它父节点的正向次大距离+
W[i][j].
上面就是dfs2要求的值。最终f[i] = max(dist[i][0],dist[i][2])
程序:
#include"stdio.h"
#include"string.h"
#include"iostream"
#define M 100009
#define inf 99999999
#define eps 1e-9
#include"math.h"
using namespace std;
struct st
{
int u,v,w,next;
}edge[M*3];
struct node
{
int max1,max2,maxj;
}p[M];
int head[M],use[M],t,dis[M],in[M],longest[M];
void init()
{
t=0;
memset(head,-1,sizeof(head));
} void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++;
}
void dfs(int u)//求正向最大距离和正向次大距离
{
use[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(!use[v])
{
dfs(v);
int MM=p[v].max1+edge[i].w;
if(p[u].max1<MM)
{
longest[u]=v;
int tt=p[u].max1;
p[u].max1=MM;
p[u].max2=tt;
}
else if(p[u].max2<MM)
{
p[u].max2=MM;
}
}
}
if(in[u]==1)
p[u].max1=p[u].max2=0;
}
void DFS(int u,int fa)//求反向最大距离
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(fa==v)continue;
if(v==longest[u])
p[v].maxj=max(p[u].maxj,p[u].max2)+edge[i].w;
else
p[v].maxj=max(p[u].maxj,p[u].max1)+edge[i].w;
DFS(v,u);
}
}
int main()
{
int n,i,j,c;
while(scanf("%d",&n)!=-1)
{
init();
memset(in,0,sizeof(in));
for(i=2;i<=n;i++)
{
scanf("%d%d",&j,&c);
add(i,j,c);
add(j,i,c);
in[i]++;
in[j]++;
}
memset(p,0,sizeof(p));
memset(use,0,sizeof(use));
for(i=1;i<=n;i++)
{
if(in[i]>1)
{
dfs(i);
DFS(i,-1);
break;
}
}
for(i=1;i<=n;i++)
{
printf("%d\n",max(p[i].max1,p[i].maxj));
}
}
return 0;
}
树形DP求各点能走到的最远距离的更多相关文章
- 浅谈关于树形dp求树的直径问题
在一个有n个节点,n-1条无向边的无向图中,求图中最远两个节点的距离,那么将这个图看做一棵无根树,要求的即是树的直径. 求树的直径主要有两种方法:树形dp和两次bfs/dfs,因为我太菜了不会写后者这 ...
- HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解
题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其 ...
- 2017 Wuhan University Programming Contest (Online Round) B Color 树形dp求染色方法数
/** 题目:Color 链接:https://oj.ejq.me/problem/23 题意:给定一颗树,将树上的点最多染成m种颜色,有些节点不可以染成某些颜色.相邻节点颜色不同.求染色方法数. 思 ...
- HDU - 3899 JLUCPC(树形dp求距离和)
JLUCPC Dr. Skywind and Dr. Walkoncloud are planning to hold the annual JLU Collegiate Programming Co ...
- 树形DP求树的重心 --SGU 134
令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...
- 树形dp - 求树的直径
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可 ...
- bzoj1912 树形dp求直径(新写法),求直径的两端点
通过回溯法可以求出直径的两个端点,同时注意有负权边的树求直径不可以用两次dfs来求,而必须用dp做 /* 分情况讨论问题 一条边也不加的情况,显然每条边要扫描两次, 该情况的答案是2(n-1) 只加一 ...
- cell_phone_network(树形dp求最小支配集)
Cell Phone Network Farmer John has decided to give each of his cows a cell phone in hopes to encoura ...
随机推荐
- 每个Web开发者都应该知道的关于URL编码的知识
本文首先阐述了人们关于统一资源定位符(URL)编码的普遍的误读,其后通过阐明HTTP场景下的URL encoding 来引出我们经常遇到的问题及其解决方案.本文并不特定于某类编程语言,我们在Java环 ...
- java_Observer Design Pattern
摘自: http://www.ntu.edu.sg/home/ehchua/programming/java/J4a_GUI.html Creating Your Own Event, Source ...
- Apache HttpComponents 学习
基本上,用户常用的就是HttpClient:它基于Http Core部分,但 Core部分太过于 low level,不建议使用,除非有特殊需要. Apache HttpComponentsTM 项目 ...
- ConfigParser.NoSectionError: No section: 'MongoDB'
场景:手动执行bat文件正常,schtasks定时执行bat文件时报错. 原因:定时执行时,ini配置文件找不到.Windows 下用 schtasks 定时执行脚本的默认起始路径为:C:\Windo ...
- e686. 显示打印窗口
The print dialog allows the user to change the default printer settings such as the default printer, ...
- php -- 读取大文件
在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file.file_get_contents之类的函数,简简单单的几行代码就能 很漂亮的完成我们所需要的功能.但当所操作的文件是一个比较大的 ...
- Python使用paramiko库远程安全连接SSH
#!/usr/bin/python #ssh import paramiko import sys,os host='127.0.0.1' user = 'whl' password = ' s = ...
- js实现密码强度
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- js点击标签时获取当前标签属性值
document.body.onclick=function(){ var obj = document.elementFromPoint(event.clientX,event.clientY); ...
- c++ ++i and i++
++i 在 i 存储的值上增加一并向使用它的表达式 ``返回" 新的, 增加后的值; 而 i++ 对 i 增加一, 但返回原来的是未增加的值. 至于++i和i++有什么区别,举个例子 1.a ...