树形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 ...
随机推荐
- 关于Unity中的定时器和委托
一.Invoke定时器 有3种定时器,这里我们讲Invoke 1.创建一个Canvas 2.对Canvas进行初始化 3.创建一个Image的UI节点作为Canvas的子节点,名字叫bg,拖进背景图片 ...
- Spring中 classpath* 和 classpath 前缀的区别
// org.springframework.core.io.support.ResourcePatternResolver /** * Pseudo URL prefix for all match ...
- 使用ffmpeg实现合并多个音频为一个音频的方法
使用ffmpeg实现合并多个音频为一个音频的方法可以使用ffmpeg的filter功能来进行这个操作,而且效果很好amerge也可以实 使用ffmpeg实现合并多个音频为一个音频的方法 可以使用ffm ...
- 测试x264编码器的低延时编码和非延时编码
最近在学x264的编码,经过大量的测试,编码1080P的视频,编码10000帧数据. 在设置为低延时编码的时候: 编码线程0,一帧耗时:7.000000 ms.编码线程0,一帧耗时:8.000000 ...
- js 自函数
函数基本概念: 函数声明:function box(){} 函数表达式:var box = function(){}; 匿名函数:function(){} 属于函数表达式 匿名函数的作用:如果将匿名函 ...
- make的自动变量和预定义变量
make的自动变量 $@ 规则目标的文件名.如果目标是档案文件的一个成员,"$@"就是档案文件的名称 $% 当目标是档案文件的一个成员时,"$%"是该成员的名称 ...
- jquery获取html元素的绝对位置和相对位置的方法
绝对位置坐标: 代码如下: $("#elem").offset().top$("#elem").offset().left 相对父元素的位置坐标: 代码如下: ...
- Win10关闭自动更新
1.搜索栏输入“组策略”后回车 2.找到计算机配置→管理模板→Windows组件→Windows更新 3.在右侧双击“配置自动更新”,然后选择“已启用”,在左下方下拉菜单中选择“2 - 通知下载并通知 ...
- JavaScript匿名函数和回调函数
匿名函数的自调函数格式: (function(){ //代码 })(); <script type="text/javascript"> (function(){ al ...
- mysql数据库,如何在登录mysql之后执行操作系统上的SQL脚本?
需求描述: 通过mysql客户端登录到mysql数据库,如何执行操作系统上的SQL脚本文件呢? 操作过程: 1.编写测试脚本文件 [mysql@redhat6 scripts]$ cat SeCoun ...