[HDOJ2196]Computer (树直径 树形DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196

给一棵树,求树上各点到某点的距离中最长的距离。注意每个点都要求。

和普通求树的直径不一样,要求每一个点,点的数量是10000因此每一个点都跑一次dfs就会超时。因此先随便dfs一个点,找到一个点后以此点为原点再找距离它最远的点,再找一次即可找到树直径两端的点。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19
20 using namespace std;
21
22 typedef struct Edge {
23     int v, w;
24     int next;
25 }Edge;
26 const int maxn = 10010;
27 int n, ecnt;
28 int head[maxn];
29 Edge e[maxn*maxn];
30 int dp[maxn];
31 int ed, lp;
32
33 void init() {
34     memset(head, -1, sizeof(head));
35     ecnt = 0;
36 }
37
38 void adde(int u, int v, int w) {
39     e[ecnt].v = v;
40     e[ecnt].w = w;
41     e[ecnt].next = head[u];
42     head[u] = ecnt++;
43 }
44
45 void dfs(int u, int pre, int len) {
46     if(len > lp) {
47         lp = len;
48         ed = u;
49     }
50     for(int i = head[u]; ~i; i=e[i].next) {
51         if(e[i].v == pre) continue;
52         dfs(e[i].v, u, len + e[i].w);
53         dp[e[i].v] = max(dp[e[i].v], len+e[i].w);
54     }
55 }
56
57 int main() {
58     // freopen("in", "r", stdin);
59     int v, w;
60     while(~scanf("%d", &n)) {
61         init();
62         for(int i = 2; i <= n; i++) {
63             scanf("%d %d", &v, &w);
64             adde(i, v, w);
65             adde(v, i, w);
66         }
67         lp = -1;
68         memset(dp, 0, sizeof(dp));
69         dfs(1, -1, 0);
70         dfs(ed, -1, 0);
71         dfs(ed, -1, 0);
72         for(int i = 1; i <= n; i++) {
73             printf("%d\n", dp[i]);
74         }
75     }
76     return 0;
77 }
时间: 2024-11-05 18:54:32

[HDOJ2196]Computer (树直径 树形DP)的相关文章

2014 Super Training #9 E Destroy --树的直径+树形DP

原题: ZOJ 3684 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3684 题意: 给你一棵树,树的根是树的中心(到其他点的最远距离最小).现在你要破坏所有叶子节点到根节点的连通,每条边破坏都需要一定能量.你有一个能量为power的武器,能破坏能量小于等于power的任何路.求最少需要的power. 解法参考博客:http://blog.csdn.net/gzh1992n/article/details/86511

CF809E Surprise me! 莫比乌斯反演、虚树、树形DP

传送门 简化题意:给出一棵\(n\)个点的树,编号为\(1\)到\(n\),第\(i\)个点的点权为\(a_i\),保证序列\(a_i\)是一个\(1\)到\(n\)的排列,求 \[ \frac{1}{n(n-1)} \sum\limits_{i=1}^n \sum\limits_{j=1}^n \varphi(a_ia_j) dist(i,j)\] 其中\(dist(i,j)\)为树上\(i,j\)两点的距离. 看到\(\varphi\)第一反应推式子 因为序列\(a_i\)是一个\(1\)到

[模拟赛10.12] 老大 (二分/树的直径/树形dp)

[模拟赛10.12] 老大 题目描述 因为 OB 今年拿下 4 块金牌,学校赞助扩建劳模办公室为劳模办公室群,为了体现 OI 的特色,办公室群被设计成了树形(n 个点 n ? 1 条边的无向连通图),由于新建的办公室太大以至于要将奖杯要分放在两个不同的地方以便同学们丢硬币进去开光,OB 想请你帮帮他看看奖杯放在哪两个办公室使得在任意一个在劳模办公室做题的小朋友能最快地找到奖杯来开光. 一句话题意:给出一个 n 个点的树,在两个合适且不同的点放上奖杯,使得每个点到最近的奖杯距离最大值最小. 输入

青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 第一种,树形dp+LCA 比赛的时候,我猜测对于不为1的n个数,其中两两互质的对数不会很多,肯定达不到n^2 然后找出所有互质的对数,然后对为1的数进行特殊处理.(初略的估计了下,小于500的大概有50个质数,将n个数平均分到这些数中,最后大概有10000*50*200=10^7) 对所有的非1质数对,采用离

【BZOJ2286】【SDOI2011】消耗战 LCA单调性(构建虚树)+树形DP

题解: 首先我们考虑每次都做一遍树形DP(树形DP自己脑补去,随便乱搞就过了). 显然这是TLE无疑的. 所以可以利用LCA单调性构建虚树. 思想: 我们发现每次树形DP有很多点用不到,但是却需要被扫过,让他们见鬼去吧! 实现: 我们只对每次扫的图插入本次询问需要的节点,以及它们的LCA. 这样询问了m个点,虚树就至多只需要2m个点(so quick). 而插入顺序上不妨利用LCA单调性来把点按dfs度排个序,然后挨个插入单调栈. 同时我们要保证单调栈维护的是一条链,也就是一旦不是链了,我们自然

[ZJOI2008]骑士(基环树,树形dp)

[ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队.于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶. 骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾.每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自

POJ 1849 Two(树的直径--树形DP)(好题)

大致题意:在某个点派出两个点去遍历所有的边,花费为边的权值,求最少的花费 思路:这题关键好在这个模型和最长路模型之间的转换,可以转换得到,所有边遍历了两遍的总花费减去最长路的花费就是本题的答案,要思考,而且答案和派出时的起点无关 求最长路两遍dfs或bfs即可,从任意点bfs一遍找到最长路的一个终点,再从这个终点bfs找到起点 //1032K 79MS C++ 1455B #include<cstdio> #include<iostream> #include<cstring

BZOJ 3162 独钓寒江雪 树同构+树形DP

题目大意:给定一棵树,求本质不同的独立集个数对1000000007取模后的值 首先独立集个数应该都会求吧- - 令f[x][0]为x这个点不选的独立集个数 f[x][1]为x这个点选的独立集个数 那么有f[x][0]=Σf[son[x]][0]+f[son[x]][1] f[x][1]=Σf[son[x]][0] 但是现在要求本质不同 说到本质不同我们很容易想到群论 但是群论显然写不了- - 于是我们考虑对树进行一下处理 首先将树有根化 为了保证形态相同的子树在有根化之后形态依然相同,我们需要找

P4383 [八省联考2018]林克卡特树lct 树形DP+凸优化/带权二分

$ \color{#0066ff}{ 题目描述 }$ 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一个叫做"LCT" 的挑战,它的规则是这样子的:现在有一个N 个点的 树(Tree),每条边有一个整数边权vi ,若vi >= 0,表示走这条边会获得vi 的收益:若vi < 0 ,则表示走这条边需要支付- vi 的过路费.小L 需要控制主角Link 切掉(