hdu2196 树形dp
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196
总算彻底理解这个题了 =.=
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=; struct Edge
{
int v;
int len;
int next;
} edge[maxn<<]; int head[maxn];
int fm[maxn],fn[maxn]; ///最远距离,以及对应的子树的序号
int sm[maxn],sn[maxn]; ///次远距离,以及其对应的子树
int k; void addedge(int u,int v,int l)
{
edge[k].v=v;
edge[k].len=l;
edge[k].next=head[u];
head[u]=k++; edge[k].v=u;
edge[k].len=l;
edge[k].next=head[v];
head[v]=k++;
} void dfs1(int u,int p) ///第一次dfs找到子树种最大的长度,和最大长度的子树的序号
{
fm[u]=; ///初始化
sm[u]=;
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
dfs1(v,u);
if(edge[i].len+fm[v]>sm[u])
{
sm[u]=edge[i].len+fm[v];
sn[u]=v;
if(sm[u]>fm[u])
{
swap(fm[u],sm[u]);
swap(fn[u],sn[u]);
}
}
}
} void dfs2(int u,int p)
{
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
if(v==fn[u])
{
if(edge[i].len+sm[u]>sm[v])
{
sm[v]=edge[i].len+sm[u];
sn[v]=u; ///开始没懂为什么还要记录结点
if(sm[v]>fm[v]) ///更新的目的就是可以找到从子树来的最大值,不记录有时候找的是次大值
{
swap(fm[v],sm[v]);
swap(fn[v],sn[v]);
}
}
}
else
{
if(edge[i].len+fm[u]>sm[v])
{
sm[v]=edge[i].len+fm[u];
sn[v]=u;
if(sm[v]>fm[v])
{
swap(fm[v],sm[v]);
swap(fn[v],sn[v]);
}
}
}
dfs2(v,u);
}
} int main()
{
int n;
while(scanf("%d",&n)==)
{
memset(head,-,sizeof(head));
k=;
int x,l;
for(int i=; i<=n; i++)
{
scanf("%d%d",&x,&l);
addedge(i,x,l);
}
dfs1(,-); ///随便选一点作为树根,那么他的父亲结点就设为-1
dfs2(,-); ///所以换成dfs1(2,-1),dfs2(2,-1) 也是可以的
for(int i=; i<=n; i++)
printf("%d\n",fm[i]);
}
return ;
}
hdu2196 树形dp的更多相关文章
- hdu2196 树形dp经典|树的直径
/* 两种做法 1.求出树直径v1,v2,那么有一个性质:任取一点u,树上到u距离最远的点必定是v1或v2 那么可以一次dfs求树v1 第二次求dis1[],求出所有点到v1的距离,同时求出v2 第三 ...
- hdu2196树形dp
有一棵树,找每个节点所能到达的最远距离是多少 dis[u][0]正向最大距离 dis[u][1]正向次大距离 dis[u][2]反向最大距离 先一边dfs求出每个节点的正向最大距离(就是 ...
- Computer(HDU2196+树形dp+树的直径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 题目: 题意:有n台电脑,每台电脑连接其他电脑,第i行(包括第一行的n)连接u,长度为w,问你每 ...
- hdu-2196 树形dp 求一个树中所有节点能到达的最远距离f[i] (其实也不难嘛!)
#include <bits/stdc++.h> using namespace std; ; struct T { int to; int w; }; vector < vecto ...
- 【树形dp小练】HDU1520 HDU2196 HDU1561 HDU3534
[树形dp]就是在树上做的一些dp之类的递推,由于一般须要递归处理.因此平庸情况的处理可能须要理清思路.昨晚開始切了4题,作为入门训练.题目都很easy.可是似乎做起来都还口以- hdu1520 An ...
- HDU2196 Computer(树形DP)
和LightOJ1257一样,之前我用了树分治写了.其实原来这题是道经典的树形DP,感觉这个DP不简单.. dp[0][u]表示以u为根的子树中的结点与u的最远距离 dp[1][u]表示以u为根的子树 ...
- HDU5834 Magic boy Bi Luo with his excited tree(树形DP)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5834 Description Bi Luo is a magic boy, he also ...
- Codeforces 543D Road Improvement(树形DP + 乘法逆元)
题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...
- POJ3162 Walking Race(树形DP+尺取法+单调队列)
题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长. 各个结点到其他结点的最远距离可以用树形DP ...
随机推荐
- UOJ#67. 新年的毒瘤
传送门 练习一下Tarjan的模板. 求一下割点,然后加个约束条件判一下特殊点,剩下的就是所求点. //UOJ 67 //by Cydiater //2016.10.27 #include <i ...
- jQuery插件之Cookie插件使用方法~
一.介绍 1-1.jQuery.Cookie.js插件是一个轻量级的Cookie管理插件.下载地址:jQuery-cookie.js 有需要的朋友,右键另存为即可! 二.使用方法 2-1.引入jQu ...
- JavaScript写在Html页面的<head></head>中
JavaScript写在Html页面的<head></head>中 ----------------- <html> <head> <style ...
- 图解c/c++多级指针与“多维”数组
声明:本文为原创博文,如有转载,请注明出处.若本文有编辑错误.概念错误或者逻辑错误,请予以指正,谢谢. 指针与数组是C/C++编程中非常重要的元素,同时也是较难以理解的.其中,多级指针与“多维”数组更 ...
- 产经新闻:公交WiFi这次能扛多久
来源:16WiFi.流量咪 http://www.16wifi.com/18820/mtbd/html/1096904.html 不靠谱也许是成长的烦恼,也可能是本性使然.公交WiFi就给人一种不靠 ...
- Hadoop概括——学习笔记<一>
之前有幸在MOOC学院抽中小象学院hadoop体验课. 这是小象学院hadoop2.X概述第一章的笔记 第一章主要讲的是hadoop基础知识.老师讲的还是比较全面简单的,起码作为一个非专业码农以及数据 ...
- android学习链接
Android studio/Gradle学习资源:http://www.cnblogs.com/licheetec/p/4475426.html
- nyoj220 推桌子(贪心算法)
这道题太坑了,from 和to有可能写反,还得正过来: 推桌子 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 The famous ACM (Advanced Co ...
- Discuzx系统 CSS 编码规范,CSS属性书写顺序
1. 属性写在一行内,属性之间.属性名和值之间以及属性与“{}”之间须有空格,例如:.class { width: 400px; height: 300px; } 2. 属性的书写顺序: ...
- JavaScript类型判断instanceof与typeof对比
经常有人会在JavaScript里写如下的方法: function checkType() { var s1 = 123; var s2 = "OK"; if (s1 instan ...