HDU 2196 Computer(树形dp经典)
2016-03-09 20:57
239 查看
原题链接
题意:
给出一棵树,求离每个节点最远的点的距离。
Sample Input
5
1 1
2 1
3 1
1 1
Sample Output
3
2
3
4
4
思路:
对于任意一个节点,要寻找其的最远距离的点,则有两种可能。对其子树的子节点的查找,对于其父节点的查找,各自找到其最远距离的节点,并比较两者的大小,即可得到最远距离的节点。
实现:
[i][0],表示顶点为i的子树的,距顶点i的最长距离
f[i][1],表示Tree(i的父节点)-Tree(i)的最长距离+i跟i的父节点距离
子节点查找:要求所有的f[i][0]很简单,只要先做一次dfs求每个结点到叶子结点的最长距离即可。然后要求f[i][1], 可以从父节点递推到子节点,
父节点查找:假设节点u有n个子节点,分别是v1,v2…vn。
如果vi不是u最长距离经过的节点,f[vi][1] = dist(vi,u)+max(f[u][0], f[u][1])
如果vi是u最长距离经过的节点,那么不能选择f[u][0],因为这保存的就是最长距离,要选择Tree(u)第二大距离secondDist。
综上f[vi][1] = dist(vi, u) + max(secondDist, f[u][1])
题意:
给出一棵树,求离每个节点最远的点的距离。
Sample Input
5
1 1
2 1
3 1
1 1
Sample Output
3
2
3
4
4
思路:
对于任意一个节点,要寻找其的最远距离的点,则有两种可能。对其子树的子节点的查找,对于其父节点的查找,各自找到其最远距离的节点,并比较两者的大小,即可得到最远距离的节点。
实现:
[i][0],表示顶点为i的子树的,距顶点i的最长距离
f[i][1],表示Tree(i的父节点)-Tree(i)的最长距离+i跟i的父节点距离
子节点查找:要求所有的f[i][0]很简单,只要先做一次dfs求每个结点到叶子结点的最长距离即可。然后要求f[i][1], 可以从父节点递推到子节点,
父节点查找:假设节点u有n个子节点,分别是v1,v2…vn。
如果vi不是u最长距离经过的节点,f[vi][1] = dist(vi,u)+max(f[u][0], f[u][1])
如果vi是u最长距离经过的节点,那么不能选择f[u][0],因为这保存的就是最长距离,要选择Tree(u)第二大距离secondDist。
综上f[vi][1] = dist(vi, u) + max(secondDist, f[u][1])
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<cmath> #include<cstring> using namespace std; typedef long long int64; const int INF = 0x3f3f3f3f; const double PI = acos(-1.0); const int MAXN = 10010; struct Node{ int v, w; }; vector<Node>adj[MAXN]; int indeg[MAXN]; int val[MAXN]; int n, m; int64 f[MAXN][2]; int vis[MAXN]; int64 dfs1(int u){ vis[u] = true; f[u][0] = 0; for(int i=0; i<adj[u].size(); ++i){ int v = adj[u][i].v; int w = adj[u][i].w; if(vis[v]) continue; f[u][0] = max(f[u][0], dfs1(v)+w); } return f[u][0]; } void dfs2(int u, int fa_w){ vis[u] = true; int max1=0, v1, max2=0, v2; for(int i=0; i<adj[u].size(); ++i){ int v = adj[u][i].v; int w = adj[u][i].w; if(vis[v]) continue; int tmp = f[v][0] + w; if(tmp > max1){ max2 = max1; v2 = v1; max1 = tmp; v1 = v; }else if(tmp == max1 || tmp>max2){ max2 = tmp; v2 = v; } } if(u != 1){ int tmp = f[u][1]; int v = -1; if(tmp > max1){ max2 = max1; v2 = v1; max1 = tmp; v1 = v; }else if(tmp == max1 || tmp>max2){ max2 = tmp; v2 = v; } } for(int i=0; i<adj[u].size(); ++i){ int v = adj[u][i].v; int w = adj[u][i].w; if(vis[v]) continue; if(v==v1){ f[v][1] = max2 + w; }else{ f[v][1] = max1 + w; } dfs2(v, w); } } int main(){ while(~scanf("%d", &n) && n){ for(int i=1; i<=n; ++i) adj[i].clear(); for(int u=2; u<=n; ++u){ int v, w; scanf("%d%d", &v, &w); adj[u].push_back((Node){v, w}); adj[v].push_back((Node){u, w}); } memset(f, 0, sizeof(f)); memset(vis, 0, sizeof(vis)); dfs1(1); memset(vis, 0, sizeof(vis)); dfs2(1, 0); for(int i=1; i<=n; ++i){ cout << max(f[i][0], f[i][1]) << endl; } } return 0;
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray
- DP Flow