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

题目:

题意:有n台电脑,每台电脑连接其他电脑,第i行(包括第一行的n)连接u,长度为w,问你每个节点能够连接的最远距离。

思路:树形dp,由于本题是一棵有根树(根节点为1),所以每个节点能到达的最远距离为max(从父亲节点往上传并到达根节点的其他子树的最远距离,从子节点到达的最远距离)。为了获得这两个信息,那么我们就需要把信息从子节点往父亲节点传和从父亲节点往子节点传,因此我们需要两个dfs,第一个处理出当前节点u从子节点能够到达的最远距离(记为dp[u][0]),次远距离(记为dp[u][1]),第二个处理从父亲节点能够到达的最远距离(记为dp[u][2]),最后每个节点能够到达的最远距离就是max(dp[u][0],dp[u][2])。我们为什么要记录dp[u][1]呢?原因是当你在第二遍dfs时,你记录dp[u][2]就得判断是dp[u][0]和dp[u][2]比较还是dp[u][1]和dp[u][2]比较(当前节点为v,v的父亲节点为u),而这个判断的依据就是u从子节点到达的最远距离是否就是通过跑v这条子链跑出来的,如果是跑这条链跑出来的,那么肯定是要用dp[u][1]来进行比较,反之就是dp[u][0]。(实在不好理解的请手动画个图辅助理解~)我们知道树的直径是树上最长链的长度,根据这题处理出来的信息我们容易知道树的直径就是max{max(dp[u][0],dp[u][2])+dp[u][0],u为1~n}。

代码实现如下:

 #include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef unsigned long long ull; #define bug printf("*********\n");
#define FIN freopen("in.txt", "r", stdin);
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define IO ios::sync_with_stdio(false),cin.tie(0); const int mod = 1e9 + ;
const int maxn = 1e4 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f; int n, u, v;
int dp[maxn][]; struct edge {
int v, w;
edge(int v = , int w = ) : v(v), w(w) {}
}; vector<edge> G[maxn]; void init() {
memset(dp, , sizeof(dp));
for(int i = ; i < maxn; i++) {
G[i].clear();
}
} void dfs1(int u) {
int v, w;
for(int i = ; i < G[u].size(); i++) {
v = G[u][i].v, w = G[u][i].w;
dfs1(v);
if(dp[v][] + w > dp[u][]) {
dp[u][] = max(dp[u][], dp[u][]);
dp[u][] = dp[v][] + w;
} else {
dp[u][] = max(dp[u][], dp[v][] + w);
}
}
} void dfs2(int u) {
int v, w;
for(int i = ; i < G[u].size(); i++) {
v = G[u][i].v, w = G[u][i].w;
if(dp[u][] == dp[v][] + w) {
dp[v][] = max(dp[u][], dp[u][]) + w;
} else {
dp[v][] = max(dp[u][], dp[u][]) + w;
}
dfs2(v);
}
} int main() {
//FIN;
while(~scanf("%d", &n)) {
init();
for(int i = ; i <= n; i++) {
scanf("%d%d", &u, &v);
G[u].push_back(edge(i, v));
}
dfs1();
dfs2();
for(int i = ; i <= n; i++) {
printf("%d\n", max(dp[i][], dp[i][]));
}
}
return ;
}

Computer(HDU2196+树形dp+树的直径)的更多相关文章

  1. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  2. computer(树形dp || 树的直径)

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  3. hdu 4607 树形dp 树的直径

    题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n)个点,至少需要走多少距离(每条边的距离是1): 思路:树形dp求树的直径r: a:若k<=r+1 ...

  4. VIJOS1476旅游规划[树形DP 树的直径]

    描述 W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流.但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员.具体说来,W市的交通网络十分简单,它包 ...

  5. POJ 3162.Walking Race 树形dp 树的直径

    Walking Race Time Limit: 10000MS   Memory Limit: 131072K Total Submissions: 4123   Accepted: 1029 Ca ...

  6. poj3162 树形dp|树的直径 + 双单调队列|线段树,好题啊

    题解链接:https://blog.csdn.net/shiqi_614/article/details/8105149 用树形dp是超时的,, /* 先求出每个点可以跑的最长距离dp[i][0|1] ...

  7. hdu-2169 Computer(树形dp+树的直径)

    题目链接: Computer Time Limit: 1000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) ...

  8. 树形DP+树状数组 HDU 5877 Weak Pair

    //树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...

  9. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

随机推荐

  1. 不同品牌交换机设置telnet方法

    H3C交换机:1.设置telnet system-view super password level 3 cipher ******telnet server enable user-interfac ...

  2. arp_ignore

    上一篇文件说了arp_announce,那么到这里arp_ignore,我们直接看代码应该也比较容易立即了 目前我知道的是arp_ignore = 0,只要IP是自己机器上的,都可以回复: 说实话就是 ...

  3. window service 创建

    1:vs中创建一个 window servece 2.右键 添加安装程序 3.更改属性视图中的Account属性为LocalService(本地服务) 更改ServiceName为你自己的服务名称   ...

  4. 【EF】Entity Framework Core 2.0 特性介绍和使用指南

    阅读目录 前言 获取和使用 新特性 项目升级和核心API变化 下一步计划 遗憾的地方 回到目录 前言 这是.Net Core 2.0生态生态介绍的最后一篇,EF一直是我喜欢的一个ORM框架,随着版本升 ...

  5. BZOJ 2303 方格染色(带权并查集)

    要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...

  6. 【bzoj2100】[Usaco2010 Dec]Apple Delivery 最短路

    题目描述 Bessie has two crisp red apples to deliver to two of her friends in the herd. Of course, she tr ...

  7. NOIP1998 提高组

    [NOIP2002] 提高组 T2.联接数 算法:贪心+字符串处理 [问题分析]: 按整数对应的字符串大到小连接,因为题目的例子都符合,但是不难找到反例:12   121 应该组成12121而非121 ...

  8. 【倍增】LCM QUERY

    给一个序列,每次给一个长度l,问长度为l的区间中lcm最小的. 题解:因为ai<60,所以以某个点为左端点的区间的lcm只有最多60种的情况,而且相同的lcm区间的连续的. 所以就想到一个n*6 ...

  9. BZOJ5011 & 洛谷4065 & LOJ2275:[JXOI2017]颜色——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5011 https://www.luogu.org/problemnew/show/P4065 ht ...

  10. BZOJ3894:文理分科——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=3894 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理 ...