萌新求助树形DP(hdu2196)
  • 板块题目总版
  • 楼主_Anchor
  • 当前回复4
  • 已保存回复4
  • 发布时间2020/8/22 00:15
  • 上次更新2023/11/6 19:42:30
查看原帖
萌新求助树形DP(hdu2196)
130387
_Anchor楼主2020/8/22 00:15

思路和常规的差不多,但有一点点不同,一遍dfs求出每个节点的子树中离它最远的长度和第二长的,第二遍dfs求出dp[x],dp[x]表示从x出发可以得到的最长的链

#include<bits/stdc++.h>
using namespace std;
int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-'){f=-1;}ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
const int N=100005;
int n;
int head[N],nex[N],to[N],val[N],idx,sonmax1[N],sonmax2[N],son1[N],son2[N],dp[N],dpson[N],maxn;
void add(int u,int v,int w){
	nex[++idx]=head[u];
	val[idx]=w;
	to[idx]=v;
	head[u]=idx;
	return ;
}
void dfs(int x,int fa){
	for(int i=head[x];i;i=nex[i]){
		int y=to[i];
		if(y==fa) continue;
		dfs(y,x);
		if(sonmax1[x]<=sonmax1[y]+val[i]){
			sonmax2[x]=sonmax1[x];
			son2[x]=son1[x];
			sonmax1[x]=sonmax1[y]+val[i];
			son1[x]=y;
		}
		else if(sonmax2[x]<sonmax1[y]+val[i]){
			sonmax2[x]=sonmax1[y]+val[i];
			son2[x]=y;
		}
	}
	return ;
}
void dfs2(int x,int fa,int k){
	if(dpson[fa]!=x&&x!=1){
		dp[x]=dp[fa]+val[k];
		if(sonmax1[x]>dp[x]){
			dp[x]=sonmax1[x];
			dpson[x]=son1[x];
		}
		else dpson[x]=fa;
	}
	else{
		dp[x]=sonmax2[fa]+val[k];
		dpson[x]=fa;
		if(dp[x]<sonmax1[x]){
			dp[x]=sonmax1[x];
			dpson[x]=son1[x];
			if(sonmax1[x]==sonmax2[x]){
				dpson[x]=son2[x];
			}
		}
	}
	for(int i=head[x];i;i=nex[i]){
		int y=to[i];
		if(y==fa) continue;
		dfs2(y,x,i);
	}
	return ;
}
int main(){
	while(~scanf("%d",&n)){
		idx=0;
		memset(head,0,sizeof(head));
		memset(dp,0,sizeof(dp));
		memset(sonmax1,0,sizeof(sonmax1));
		memset(sonmax2,0,sizeof(sonmax2));
		for(int i=2;i<=n;i++){
			int v=read(),w=read();
			add(v,i,w);
		}
		dfs(1,0);
		dfs2(1,0,0);
		for(int i=1;i<=n;i++){printf("%d\n",dp[i]);}
	}
	return 0;
}
/*
5
1 2
2 1
3 1
1 1
*/

2020/8/22 00:15
加载中...