hdu2196 Computer【树形DP】【换根法】
Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 34390 Accepted Submission(s): 5383
Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
1 1
2 1
3 1
1 1
2
3
4
4
题意:
一棵有n个节点的树,有权边。问每个节点到其他节点的最远距离分别是多少。
思路:
如果固定一个节点,那么dfs找最远的距离就可以了。用dp[i]表示以i为根的子树中,i可到的最远距离。
对于任意一个节点i,他到达的最远节点有可能在子树中,也有可能不在子树中。所以我们分别找到子树中的最远距离和不在子树中的最远距离。
dfs1就是用dp存储了在子树中的最远距离。
dfs2就是把当前节点换到了根的位置,用f存储不在子树中的最远距离。那么他到他子树节点的距离是变短了的就不用管了。
把i换成根,把i的父亲father换下去,如果i在i的父亲这棵子树的最长路径上。father换下去之后,就要考虑原本以father为根的子树的第二长路径。
如果i不在father的最长路径上,那就是在f和dp中找大的加上当前路径长度。
//#include <bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<map>
#include<set> #define inf 0x3f3f3f3f
using namespace std;
typedef long long LL; const int maxn = ;
int head[maxn], dp[maxn], f[maxn], second[maxn], longest[maxn];
struct node{
int v;
int nxt;
int weight;
}edge[maxn * ];
int n, cnt; void addedge(int u, int v, int w)
{
edge[cnt].v = v;
edge[cnt].weight = w;
edge[cnt].nxt = head[u];
head[u] = cnt++;
edge[cnt].v = u;
edge[cnt].weight = w;
edge[cnt].nxt = head[v];
head[v] = cnt++;
} void dfs1(int rt, int fa)
{
for(int i = head[rt]; i != -; i = edge[i].nxt){
int son = edge[i].v;
if(son == fa)continue;
dfs1(son, rt);
//dp[rt] = max(dp[rt], dp[son] + edge[i].weight);
if(dp[son] + edge[i].weight > dp[rt]){
longest[rt] = son;
second[rt] = max(second[rt], dp[rt]);
dp[rt] = dp[son] + edge[i].weight;
}
else if(second[rt] < dp[son] + edge[i].weight){
second[rt] = dp[son] + edge[i].weight;
}
}
} void dfs2(int rt, int fa)
{
for(int i = head[rt]; i != -; i = edge[i].nxt){
int son = edge[i].v;
if(son == fa)continue;
if(longest[rt] == son)f[son] = max(f[rt], second[rt]) + edge[i].weight;
else f[son] = max(f[rt], dp[rt]) + edge[i].weight;
dfs2(son, rt);
}
} int main(){
while(scanf("%d", &n) != EOF){
cnt = ;
memset(head, -, sizeof(head));
for(int i = ; i <= n; i++){
int u, w;
scanf("%d%d", &u, &w);
addedge(u, i, w);
}
memset(dp, , sizeof(dp));
memset(second, , sizeof(second));
memset(longest, , sizeof(longest));
memset(f, , sizeof(f));
dfs1(, ); dfs2(, );
//f[1] = dp[1];
for(int i = ; i <= n; i++){
printf("%d\n", max(dp[i], f[i]));
}
}
return ;
}
hdu2196 Computer【树形DP】【换根法】的更多相关文章
- bzoj 3743 [Coci2015]Kamp——树形dp+换根
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 树形dp+换根. “从根出发又回到根” 减去 “mx ” . 注意dfsx里真的要改那 ...
- poj3585 Accumulation Degree[树形DP换根]
思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...
- 树形dp换根,求切断任意边形成的两个子树的直径——hdu6686
换根dp就是先任取一点为根,预处理出一些信息,然后在第二次dfs过程中进行状态的转移处理 本题难点在于任意割断一条边,求出剩下两棵子树的直径: 设割断的边为(u,v),设down[v]为以v为根的子树 ...
- poj3585 Accumulation Degree(树形dp,换根)
题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...
- [题解](树形dp/换根)小x游世界树
2. 小x游世界树 (yggdrasi.pas/c/cpp) [问题描述] 小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当 ...
- HDU2196 - Computer(树形DP)
题目大意 给定一颗n个结点的树,编号为1~n,要求你求出每个结点能到达的最长路径 题解 用动态规划解决的~~~~把1 当成树根,这样就转换成有根树了.我们可以发现,对于每个结点的最长路,要么是从子树得 ...
- cf219d 基础换根法
/*树形dp换根法*/ #include<bits/stdc++.h> using namespace std; #define maxn 200005 ]; int root,n,s,t ...
- 题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)
写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ) 题目 题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量. 以这道题来介绍二次扫描和换 ...
- poj 3585 Accumulation Degree(二次扫描和换根法)
Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...
- poj3585树最大流——换根法
题目:http://poj.org/problem?id=3585 二次扫描与换根法,一次dfs求出以某个节点为根的相关值,再dfs遍历一遍树,根据之前的值换根取最大值为答案. 代码如下: #incl ...
随机推荐
- linux -- #!/bin/bash
#!/bin/bash是指此脚本使用/bin/bash来解释执行. 其中,#!是一个特殊的表示符,其后,跟着解释此脚本的shell路径. bash只是shell的一种,还有很多其它shell,如:sh ...
- C++測量一段代码的执行时时间
在电脑里发现的一段C++代码,尽管自己不做C++开发了.还是贴出来,给须要的人 LARGE_INTEGER BegainTime ; LARGE_INTEGER EndTime ; LARGE_INT ...
- JQuery元素控制方法汇总
1.在元素内部追加内容 $("元素名").append(content) 2.在元素中的不同位置追加内容 $("元素名").appendTo(content) ...
- el表达式取值优先级
不同容器中存在同名值时,从作用范围小到大的顺序依次尝试取值:pageContext->request->session->application
- HttpClient传递Cookie
使用代码访问http资源,我们通常用WebRequest,当然,HttpClient提供了更方便的封装,我用得更多.只是碰到一些需要(cookie)鉴权的情况,需要把cookie伴随请求一起发到服务器 ...
- Unity+高通Vuforia SDK——AR
一.AR概念: 增强现实(Augmented Reality,简称AR),是在虚拟现实的基础上发展起来的新技术,也被称之为混合现实.是通过计算机系统提供的信息增加用户对现实世界感知的技术,将虚拟的信息 ...
- ROS节点理解--5
理解 ROS节点(原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/) Description: 本教程主要介绍 ROS 图(graph)概念 并讨 ...
- POJ 1947 Rebuilding Road(树形DP)
Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, n ...
- GIS-ArcGIS 数据库备份还原
Create directory sdebak as 'E:\10_DataFile'; alter system set deferred_segment_creation=false; ALTER ...
- GIS-ArcGIS JS API FeatureLayer图层绑定事件的几种方式
一.以下四种方式均可以 importantProvinceLayer.on("click", DoIdentify); dojo.connect(importantProvince ...