*HDU 2196 - Computer(树形DP)
来源:互联网 发布:mac系统怎么制作铃声 编辑:程序博客网 时间:2024/05/16 16:14
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=2196
题意:
n个点,n-1条边,给出边权。求出每个节点最远的点的距离。
思路:
以1作为树根。
[插入]
如图,要得到节点2的最长距离,距离L1 是节点子树的最远距离,另一个距离L2 是图中的红色部分的最远距离+dis(2,1),结果为max(L1,L2)。
dp【v】【0】:记录节点v的子树的最远距离。此部分dfs1实现。
dp【v】【1】:记录v的父亲节点u 除了节点v的子树 的最远距离 + dis(u,v)。
实现方法为由父节点推到子节点。分为两种情况:
1. 如果v不是u的最长边上的点,则dp【v】【1】 = dis(u,v)+ max(dp【u】【0】, dp【u】【1】);
2. 如果v是u的最长边上的点,则 dp【v】【1】 = dis(u,v)+ max(second_long , dp【u】【1】);
注意答案是long long。
AC.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;typedef long long ll;const int maxn = 1e4+10;int n;int head[maxn], tot;struct Edge { int to, next; ll w;}edge[2*maxn];void addedge(int u, int v, ll w){ edge[tot].to = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++;}ll dp[maxn][2];bool vis[maxn];ll dfs1(int u){ if(dp[u][0]) return dp[u][0]; vis[u] = 1; for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; ll w = edge[i].w; if(vis[v]) continue; dp[u][0] = max(dp[u][0], dfs1(v) + w); } return dp[u][0];}void dfs2(int u){ vis[u] = 1; ll max1 = 0, max2 = 0, w, tmp; int v, v1, v2; for(int i = head[u]; ~i; i = edge[i].next) { v = edge[i].to; w = edge[i].w; if(vis[v]) continue; tmp = dp[v][0] + w; if(tmp > max1) { max2 = max1; max1 = tmp; v1 = v; } else if(max1 == tmp || tmp > max2) max2 = tmp; } if(u != 1) { tmp = dp[u][1]; v = -1; if(tmp > max1) { max2 = max1; max1 = tmp; v1 = v; } else if(max1 == tmp || tmp > max2) max2 = tmp; } for(int i = head[u]; ~i; i = edge[i].next) { v = edge[i].to; w = edge[i].w; if(vis[v]) continue; if(v == v1) dp[v][1] = max2 + w; else dp[v][1] = max1 + w; dfs2(v); }}void init(){ tot = 0; memset(head, -1, sizeof(head)); memset(dp, 0, sizeof(dp));}int main(){ //freopen("in", "r", stdin); while(~scanf("%d", &n)) { init(); for(int i = 2; i <= n; ++i) { int u; ll w; scanf("%d%I64d", &u, &w); addedge(u, i, w); addedge(i, u, w); } memset(vis, 0, sizeof(vis)); dfs1(1); memset(vis, 0, sizeof(vis)); dfs2(1); for(int i = 1; i <= n; ++i) { cout<<max(dp[i][0], dp[i][1])<<endl; } } return 0;}
0 0
- HDU 2196 Computer(树形dp)
- 【树形DP】 HDU 2196 Computer
- HDU 2196 Computer(树形DP)
- Hdu 2196 Computer(树形dp)
- Computer - HDU 2196 树形dp
- Hdu 2196 Computer (树形dp)
- HDU 2196 Computer | 树形dp
- 【树形DP】 HDU 2196 Computer
- HDU 2196 Computer (树形DP)
- hdu 2196 Computer (树形dp)
- *HDU 2196 - Computer(树形DP)
- [HDU 2196] Computer 树形dp
- HDU 2196Computer 树形dp
- 【hdu】2196 Computer【树形dp】
- HDU 2196 Computer [树形dp]
- hdu 2196 Computer(树形DP)
- 树形DP-HDU-2196-Computer
- 【HDU】2196 Computer 树形dp
- [IOS] Class Memory Analysis
- python面向对象
- NLog 相关
- 《汇编语言》第二版 王爽著 第八章 数据处理的两个基本问题 要点
- 51 单片机内存的认识
- *HDU 2196 - Computer(树形DP)
- LIS longest Increasing subarray 最长递增子序列
- POJ 1328 Radar Installation(贪心)
- C++ 智能指针详解
- 青岛高收费电话加盟 2014好项目 电话群呼器
- 指针使用注意事项
- 每天一个Linux命令-11(Netstat 详解)
- 腾讯、阿里2014实习招聘面经
- hdu 5294 Tricks Device(最短路)