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]); 求解 ...
随机推荐
- [RxJS] Creation operators: from, fromArray, fromPromise
The of() operator essentially converted a list of arguments to an Observable. Since arrays are often ...
- [ES6] ... spread operator
var parts = ['shoulders', 'knees']; var lyrics = ['head', ...parts, 'and', 'toes']; // ["head&q ...
- Topcoder SRM 637 (Div.2)
A.GreaterGameDiv2 不能更水 #line 7 "GreaterGameDiv2.cpp" #include<cstdio> #include <c ...
- 第1章 你真的了解C#吗?
什么是C#? C#是由微软公司开发的一种面向对象且运行于.Net Framework之上的高级程序设计语言,发布于2000年6月. 什么是.Net Framework 我们可以这样去理解.Net Fr ...
- sql server 导出
http://ssat.codeplex.com/SourceControl/latest 用于连接sql server
- maven自动下载jar包
只需要修改pom文件即可.需要哪个jar包,在pom中就配置哪个(还包括手动向仓库中添加) 例如 http://blog.csdn.net/beyondlpf/article/details/8592 ...
- Terminating app due to uncaught exception 'NSUnknownKeyException', reason: xxxx
出现错误的情景: 使用Swift自定义Cell, 然后将这个Cell在OC中使用, 由于为了能够在OC中使用和使用起来命名比较规范 我在Swift自定义的Cell前加了 @objc(DSProduct ...
- iOS 改变UITextField中光标颜色
第一种: [[UITextField appearance] setTintColor:[UIColor blackColor]]; 这个方法会影响整个app的所有UITextFiled... 第二种 ...
- 洛谷 P1316 丢瓶盖
P1316 丢瓶盖 题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以 ...
- ComboBox相关操作
取组合框文本示例: 1 void ShowDlgWage::OnCbnSelendokCombo1() { // TODO: 在此添加控件通知处理程序代码 CString str; int i; i ...