树形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 ...
随机推荐
- 45本免费的JavaScript书籍资源收集
JavaScript目前变得越来越流行,已经变成了Web开发必备的语言,加之其跨平台的特性,使得在一切皆为JavaScript的移动互联网时代大有作为. 同时,我们看到,在过去的这一年的软件开发中,J ...
- 关掉firefox(火狐)和palemoon地址栏自动加www.前缀功能【转】
常用palemoon调试网站域名,它会很“贴心”的给你输入的网址前加上www.前缀,可有些域名前并没有www前缀,这样就导致了无法打开网站,今天学习下关闭它的这个功能. 打开firefox,在地址栏输 ...
- 在Access中执行SQL语句
Access在小型系统开发中等到了广泛使用.虽然Access提供了可视化的操作方法,但许多开发人员还是喜欢直接用SQL语句操作数据表.如何在Access中打开SQL视图,对于初次使用Access的程序 ...
- unity3d绘画手册-------地形高度调节
高度 所有地形 (terrain) 编辑工具的使用都很简单.您可以在场景视图 (scene view)中逐步绘制地形 (terrain).对于高度工具和其他所有工具,您只需选中工具,然后在场景视图 ( ...
- 模式识别之线性判别---naive bayes朴素贝叶斯代码实现
http://blog.csdn.net/xceman1997/article/details/7955349 http://www.cnblogs.com/yuyang-DataAnalysis/a ...
- (转)一种开源的跨平台视频开发框架:VideoLAN - VLC media player
VLC原先是几个法国的大学生做的项目,后来他们把VLC作为了一个开源的项目,吸引了来自世界各国的很多优秀程序员来共同编写和维护VLC,才逐渐变成了现在这个样子.至于为什么叫VideoLan Clien ...
- CentOS 7在桌面添加快捷方式
直接把 /usr/share/applications 对应的 xxx.desktop 文件复制到桌面就OK!比如要在桌面创建Google Chrome Browser的快捷方式,直接在找到 /usr ...
- git call failed: [git clone Could not resolve host: git.openstack.org
git config --global http.proxy $http_proxy git config --global https.proxy $https_proxy ref: http:// ...
- 教你如何架设linux邮件服务器postfix
检查linux是否有安装postfix和dovecot 检查命令如下: Rpm -qa |grep postfix; Rpm –qa |grep dovecot; 如果没有显示任何数据,表明没有安 ...
- 类似股软(大智慧)之键盘精灵的 vc2008--UNICODE 环境实现
键盘精灵是指,当按下键盘上任意一个数字.字母或符号的时候,都会弹出“键盘精灵”,其类似于股票软件(如大智慧)中的.可以在这里面输入中英文和数字搜索您想要的东西.可以通过输入代码.名称或名称的汉语拼音首 ...