HDU 2196 Computer(经典树形DP)
2024-08-26 23:45:59
题意自己看(猜)
题解
这题很经典,就是记录dp[i][0/1/2]分别代表,从i点向下最大和次大深度,和向上最大深度。
然后转移就行了。
我的写法可能太丑了。死活调不出来,写了一个漂亮的
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=;
int dp[N][],cnt,head[N],longest[N],n;
struct edge{
int to,nxt,w;
}e[N*];
void add(int u,int v,int w){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
e[cnt].w=w;
head[u]=cnt;
}
void dfs1(int u,int fa){
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
dfs1(v,u);
if(dp[v][]+e[i].w>dp[u][]){
longest[u]=v;
dp[u][]=dp[u][];
dp[u][]=dp[v][]+e[i].w;
}
else if(dp[v][]+e[i].w>dp[u][]){
dp[u][]=dp[v][]+e[i].w;
}
}
}
void dfs2(int u,int fa){
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
if(v==longest[u])dp[v][]=max(dp[u][],dp[u][])+e[i].w;
else dp[v][]=max(dp[u][],dp[u][])+e[i].w;
dfs2(v,u);
}
}
int main(){
while(scanf("%d",&n)!=EOF){
memset(head,,sizeof(head));
cnt=;
memset(dp,,sizeof(dp));
memset(longest,,sizeof(longest));
for(int i=;i<=n;i++){
int f,w;
scanf("%d%d",&f,&w);
add(f,i,w);add(i,f,w);
}
dfs1(,);
dfs2(,);
for(int i=;i<=n;i++){
printf("%d\n",max(dp[i][],dp[i][]));
}
}
return ;
}
最新文章
- SQL 中的 AND OR
- sphinx应用
- linux服务器加硬盘扩容
- 7个你可能不认识的CSS单位
- Bootstrap 固定定位(Affix)
- hello world是怎样运行的?
- js时间字符串转Date对象
- java中System.getProperty()的作用及使用
- UWP 返回顶部按钮
- shell脚本基础1 概述及变量
- Windows系统盘符错乱导致桌面无法加载。
- Spinner 默认选中
- Hadoop的单机模式、伪分布式模式和完全分布式模式
- js高级-数组的map foreach 方法
- linux下配置tomcat集群的负载均衡
- Cookie利用神器:CookieHacker
- js实现点击div以外区域,隐藏div区域
- postgresql 的操作
- linux下定时器介绍1
- 小白学Linux