HDU2196-Computer
原题连接:
http://acm.hdu.edu.cn/showproblem.php?pid=2196
思路:
好了,无敌了,经过昨晚4个钟头+今上午1个小时的奋战,这题终于被我AC了
收获的确是不小。。呵呵
一步步的总结吧,题意就是让你求给定树中某一个点到其他任意点的最大权值
(1)总体的思路。一个点到其他任意点的最大权值只有两种可能性,一个是这个值来自的子树,另一个是这个值来自父结点,因为这个点通往外界的出口就只有这两条了。
(2)首先是求出子树的最大权值,这个只需要用一个dfs+记忆化搜索,这里之所以dfs一个根结点就可以得到所有点的f[i][0]是因为,在遍历所有叶子的过程中,它实际就是路过了所有的结点——只有这样才有可能便利到所有的叶子。
(3)其次要求每个节点的f[i][1],即通过自己的父节点能够达到的最大权值,那么这个值有两种可能性。就这一块纠结了能有几个小时,如果在一开始就很严密的给总结好,就不会有那么多的麻烦了。一是父节点的其他分支,(注!如果这个分枝不存在,那么这个值就是w)另一个是父节点的父节点,我们在这两个值中选择一个更大的赋给f[i][1]。
(4)还有一个坑了好久的地方是求某节点到叶子的第二长距离,这个也是要考虑到所有的大小可能性,然后仔细的做好分类
(5)最后说一下这个题的数据结构,即树的存储方式。用了一个struct里面带着两个变量v和w来存储子树和到达子树的距离,然后用一个root数组来存父节点的位置。
(6)last but not least,这个题在网上好像所有人都是用的两个dfs的做法,而我自创了一个dfs+bfs的做法,或许5个h就是代价吧。。。
#include <iostream>
#include <vector>
#include <cstring>
#include <queue>
#define MAX 10007
using namespace std; int n;
int max(int a,int b)
{
return a>b?a:b;
}
struct node {
int v,w;
};
vector<node> son[MAX];
__int64 f[MAX][];
__int64 dp[MAX];
int root[MAX];
queue<int> q;
int end[MAX]; __int64 dfs1(int s)
{
if(f[s][] != -) return f[s][];
else {
int len = son[s].size();
for(int i = ;i < len;i++)
{
int v = son[s][i].v;
int w = son[s][i].w;
int nn = w+dfs1(v);
if(nn>f[s][]) {
if(f[s][] == f[s][])
f[s][] = nn;
else {
f[s][] = f[s][];
f[s][] = nn;
}
}
else if(nn>f[s][])
f[s][] = nn;
}
return f[s][];
}
} void bfs()
{
while(!q.empty())
{
int s = q.front();
q.pop();
int len = son[s].size();
for(int i = ;i < len;i++)
{
int v = son[s][i].v;
int w = son[s][i].w; if(f[v][]+w != f[s][])
f[v][] = f[s][]+w;
else {
if(f[s][] != -)
f[v][] = w+f[s][];
else
f[v][] = w;
} f[v][] = max(f[v][],f[s][]+w); dp[v] = max(f[v][],f[v][]);
q.push(v);
}
}
} int main()
{
while(cin>>n)
{
memset(root,-,sizeof(root));
for(int i = ;i <= n;i++)
son[i].clear();
int v,w;
for(int i = ;i <= n;i++)
{
cin>>v>>w;
//构建树
node tmp;
tmp.v = i;
tmp.w = w;
son[v].push_back(tmp);
root[i] = v;
}
memset(f,-,sizeof(f));
for(int i = ;i <= n;i++)
if(son[i].empty())
f[i][] = ;
//dfs求所有的点到叶子节点的最长距离
dfs1();
//bfs求所有点的f[i][1]
memset(dp,-,sizeof(dp));
dp[] = f[][];//树根节点已经成为了男人
q.push();
bfs(); for(int i = ;i <= n;i++)
cout<<dp[i]<<endl;
}
return ;
}
HDU2196-Computer的更多相关文章
- hdu2196 Computer【树形DP】【换根法】
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- 【HDU2196 Computer】经典树形dp
http://acm.hdu.edu.cn/showproblem.php?pid=2196 题意:有n台电脑相连,让你求每台电脑与离它最远的那台电脑的距离. 思路:两遍搜索即可,第一遍从上到下,第二 ...
- HDU2196 Computer(树形DP)
和LightOJ1257一样,之前我用了树分治写了.其实原来这题是道经典的树形DP,感觉这个DP不简单.. dp[0][u]表示以u为根的子树中的结点与u的最远距离 dp[1][u]表示以u为根的子树 ...
- HDU-2196 Computer (树形DP)
题目大意:在一棵带边权的有根树中,对于每个点,找出它与离它最远的那个点的之间的距离. 题目分析:对于一个点,离它最远的点只有两种情况,一是它到叶子节点的最远距离,一是与它父亲的距离加上他的父亲到叶子节 ...
- HDU2196 - Computer(树形DP)
题目大意 给定一颗n个结点的树,编号为1~n,要求你求出每个结点能到达的最长路径 题解 用动态规划解决的~~~~把1 当成树根,这样就转换成有根树了.我们可以发现,对于每个结点的最长路,要么是从子树得 ...
- hdu2196 Computer待续
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #i ...
- [hdu2196]Computer树的直径
题意:求树中距离每个节点的最大距离. 解题关键:两次dfs,第一次从下向上dp求出每个节点子树中距离其的最大距离和不在经过最大距离上的子节点上的次大距离(后序遍历),第二次从上而下dp求出其从父节点过 ...
- [HDU2196]Computer(DP)
传送门 题意 给出一棵树,求离每个节点最远的点的距离 思路 对于我这种菜鸡,真是难啊. 每个点的距离它最远的点,除了在它子树中的,还有在它子树之外的,所以这几个状态都得表示出来. 我们能够很简单的求出 ...
- HDU2196 Computer【换根dp】
题目传送门 题意: 给定一个$N$个点的树,第$i$条边的长度是$A_i$,求每个点到其他所有点的最长距离.数据范围:$n ≤ 10000$,$A_i ≤ 10_9$ 分析 首先,从随便哪个节点($1 ...
- HDU2196 Computer (树形DP-换根)
dp[u][0]表示u向下走的最大距离: dp[u][1]表示u向下走的次大距离: dp[u][2]表示u向上走的最大距离: 最后的答案就是每个点的max(dp[u][0],dp[u][2]); 求解 ...
随机推荐
- javascript內容向上不間斷滾動
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Android 百度地图 SDK v3.0.0 (一)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37729091 最近公司要把百度地图集成的项目中,于是我就研究了一天百度地图的SD ...
- Linux Kernel basics
Linux内核作用: The Linux kernel is the heart of the operating system. It is the layer between the user w ...
- 在公网(internet)上建立website时不能用http访问
我们在internet的IDC提供的虚拟机上建了新的web site, 域名也从阿里巴巴那里得到二级域名,也经过映射到了虚机的IP, 在本机都可以用域名以Http方式访问,但在internet上的其它 ...
- 一条insert语句批量插入多条记录
一条insert语句批量插入多条记录 常见的insert语句,向数据库中,一条语句只能插入一条数据: insert into persons (id_p, lastname , firstName, ...
- (转)Discuz!NT图文安装教程
不同目录下的安装方法根据目前大家对论坛的使用需求,在安装上面大致有三种情况,站点根目录下安装,站点虚拟目录下安装和站点子目录下安装. 1.根目录安装 根目录安装是最简单也是稳定系数最高的安装和使用方式 ...
- ajax+ashx 完美实现input file上传文件
1.input file 样式不能满足需求 <input type="file" value="浏览" /> IE8效果图: Firefox效 ...
- Zend Framework
参考:http://www.php100.com/manual/ZendFramework/index.html 1.1. 概述 Zend Framework (ZF) 是一个开放源代码的 PHP5 ...
- C#垃圾回收
析构方法: 我们知道引用类型都有构造方法(constructor),相对应的也有一个析构方法(destructor).顾名思义,构造方法,就是在创建这个对象时,要执行的方法.例如,我们可以通过构造方法 ...
- 使用C#代码追加和提交文件到SVN服务器
windows系统下使用svn的命令需要安装一个插件,下载地址:http://sourceforge.net/projects/win32svn/?source=typ_redirect 安装后程序会 ...