SGU 149 树形DP Computer Network
这道题搜了一晚上的题解,外加自己想了半个早上,终于想得很透彻了。于是打算好好写一写这题题解,而且这种做法比网上大多数题解要简单而且代码也比较简洁。
首先要把题读懂,把输入读懂,这实际上是一颗有向树。第i(2≤i≤n)行的两个数u,d,其中u是i的父亲结点,d是距离。
第一遍DFS我们可以计算出以u为根的子树中,距离u最远的结点的距离d(u, 0)以及次远的距离d(u, 1)。而且,这两个不在u的同一棵子树中,如果u只有一个孩子,那么d(u, 1) = 0
第一遍DFS完以后,因为1是整棵树的跟,所以d(1, 0)就是距离1最远的距离。然后第二遍DFS,这次是用根的信息来更新它的子节点,此时d(u,0)d(u,1)的含义变为整棵树中距u最长和次长的距离。
如图:

红线代表距u最长的距离,绿线是次长。因为最长距离在v1的子树中,所以就用dis(u, v1) + d(u, 1)(也就是那条绿线)来更新距v1的最长和次长距离; 用dis(u, v2) + d(u, 0)(那条红线)来更新距v2的最长次长距离。
因此最终答案就是d(u, 0)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int maxn = + ;
vector<int> G[maxn], C[maxn];
int n; int d[maxn][]; void dfs(int u)
{
for(int i = ; i < G[u].size(); i++)
{
int v = G[u][i];
dfs(v);
int t = d[v][] + C[u][i];
if(t > d[u][]) swap(t, d[u][]);
if(t > d[u][]) swap(t, d[u][]);
}
} void dfs2(int u)
{
for(int i = ; i < G[u].size(); i++)
{
int v = G[u][i], t, w = C[u][i];
if(d[v][] + w == d[u][]) t = w + d[u][];
else t = w + d[u][];
if(t > d[v][]) swap(t, d[v][]);
if(t > d[v][]) swap(t, d[v][]);
dfs2(v);
}
} int main()
{
scanf("%d", &n);
for(int u = ; u <= n; u++)
{
int v, d; scanf("%d%d", &v, &d);
G[v].push_back(u); C[v].push_back(d);
} dfs();
dfs2(); for(int i = ; i <= n; i++) printf("%d\n", d[i][]); return ;
}
代码君
SGU 149 树形DP Computer Network的更多相关文章
- HDU 2196 树形DP Computer
题目链接: HDU 2196 Computer 分析: 先从任意一点开始, 求出它到其它点的最大距离, 然后以该点为中心更新它的邻点, 再用被更新的点去更新邻点......依此递推 ! 代码: ...
- SGU 149. Computer Network( 树形dp )
题目大意:给N个点,求每个点的与其他点距离最大值 很经典的树形dp...很久前就想写来着...看了陈老师的code才会的...mx[x][0], mx[x][1]分别表示x点子树里最长的2个距离, d ...
- 树形DP求树的重心 --SGU 134
令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...
- HDU 2196.Computer 树形dp 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- computer(树形dp || 树的直径)
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- 树形dp compare E - Cell Phone Network POJ - 3659 B - Strategic game POJ - 1463
B - Strategic game POJ - 1463 题目大意:给你一棵树,让你放最少的东西来覆盖所有的边 这个题目之前写过,就是一个简单的树形dp的板题,因为这个每一个节点都需要挺好处 ...
- HDU2196 Computer(树形DP)
和LightOJ1257一样,之前我用了树分治写了.其实原来这题是道经典的树形DP,感觉这个DP不简单.. dp[0][u]表示以u为根的子树中的结点与u的最远距离 dp[1][u]表示以u为根的子树 ...
- HDU 2196 Computer 树形DP 经典题
给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...
- poj3417 Network 树形Dp+LCA
题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果 ...
随机推荐
- nodejs 学习(4) express+mongoose
一.关于安装和启动: 1.设置环境变量:D:\Program Files\MongoDB\bin 2.启动时需要cd到bin 目录,然后 mongod --dbpath "D:\mongdb ...
- Crusher Django 学习笔记3 学习使用模板系统
http://crusher-milling.blogspot.com/2013/09/crusher-django-tutorial3-using-template.html 顺便学习一下 goag ...
- nodejs express session用法(含保存到redis)
普通用法: var express = require('express'); var session = require('express-session'); var app = express( ...
- kafka系列一:单节点伪分布式集群搭建
Kafka集群搭建分为单节点的伪分布式集群和多节点的分布式集群两种,首先来看一下单节点伪分布式集群安装.单节点伪分布式集群是指集群由一台ZooKeeper服务器和一台Kafka broker服务器组成 ...
- bootstrop媒体对象、面板和Well
媒体对象 <div class="media"> <div class="media-left"> < ...
- ios,弹窗遮罩滚动穿透解决方案
- js如何调用电脑的摄像头
闲来无事,用js写了一个调用摄像头的demo,并用canvas显示保存.这个功能很实用,比如上传用户的头像,即时拍照及时上传. Html: <video width="200px&qu ...
- imageview加载本地和网络图片
ImageView是Android程序中经常用到的组件,它将一个图片显示到屏幕上. 在UI xml定义一个ImageView如下: public void onCreate(Bundle savedI ...
- 关于svn提交的时候强制写注释
本文固定链接: http://www.linuxyan.com/linux-service/229.html 转载请注明: admin 2012年09月29日 于 ㄨ销声匿迹.Linux 发表 在sv ...
- Android学习总结(五)———— BroadcastReceiver(广播接收器)的基本概念和两种注册广播方式
我们学完了Android四大组件的Activity和Service了,接下来我们一起来学习Android四大组件的第三个吧:BroadcastReceiver(广播接收者),计划如下图: 一.Broa ...