*HDU 2196 - Computer(树形DP)
2015-07-31 21:52
363 查看
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=2196
题意:
n个点,n-1条边,给出边权。求出每个节点最远的点的距离。
思路:
以1作为树根。
![](https://img-blog.csdn.net/20150731214128340)
[插入]
如图,要得到节点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.
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; }
相关文章推荐
- HDU 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 1000
- HDU 1001
- HDU 1622 Trees On The Level
- HDU 1063 Exponentiation
- Hdu5033
- HDU 1166 敌兵布阵
- HDU Rightmost Digit
- hdu 1002
- 贪心 hdu 1003
- hdu 1004