您的位置:首页 > 其它

computer hdoj 2196树形dp

2013-07-28 14:26 435 查看
以前也写过树形dp的题,但是现在的感觉就是很无从下手,明白那个意思不知道该怎么写,也不知道要从哪里入手,很茫然,然后在别人的思路下写了一道就是这题。。。

思路:建树,进行两次dfs,第一次从根向子女进行搜索,记录的时从根到子女的第一大的值和第二大的值,然后就是再从子女向根进行搜索,根据子女所在的路径来确定是取父节点上第一大的值还是第二大的值,然后就是取最值了,完全看的别人的没有一点成就感,今下午就一直写树形dp了!!!

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
#include<map>
using namespace std;

#define rep(i,n) for(int i=0; i<(n); ++i)
#define repf(i,n,m) for(int i=(n); i<=(m); ++i)
#define repd(i,n,m) for(int i=(n); i>=(m); --i)
#define ll long long
#define inf 1000000000
#define exp 0.000000001
#define N 10010

struct node
{
int y,len;
node(){}
node(int _y,int _len):y(_y),len(_len){}
};
vector<node>vec
;
int fa
,flen
;
int dp
;
int len
,len2
;//最远和次远的
int nod
;//记录最远的距离时的子节点的
int n;

void init()
{
memset(dp,0,sizeof(dp));
memset(len,0,sizeof(len));
memset(len2,0,sizeof(len2));
}

void dfs(int s)
{
// cout<<" "<<s<<" "<<vec[s].size()<<endl;
if(vec[s].size()==0)
{
len[s]=len2[s]=0; nod[s]=-1;
return ;
}
rep(i,vec[s].size())
{
int y=vec[s][i].y;
dfs(y);
// cout<<s<<endl;
if(len[y]+vec[s][i].len>=len[s])
{
len2[s]=len[s];
len[s]=len[y]+vec[s][i].len;
nod[s]=y;//最大的那个子节点时y
}
else
len2[s]=max(len2[s],len[y]+vec[s][i].len);
// cout<<len[s]<<" "<<len2[s]<<endl;
}
}

int find(int s,int pre)
{
// cout<<s<<" "<<pre<<endl;
if(s==1)
{
// cout<<"sdf:"<<nod[s]<<" "<<pre<<endl;
if(nod[s]==pre) return len2[s];
else return len[s];
}
int fat=fa[s];//父亲的
int sum;
if(nod[fat]==s)
sum=len2[fat];
else sum=len[fat];
// cout<<s<<" "<<sum<<endl;
return flen[s]+max(sum,find(fa[s],s));
}

int main()
{
while(~scanf("%d",&n))
{
repf(i,1,n) vec[i].clear();
int x,y;
repf(i,2,n)
{
scanf("%d%d",&x,&y);
vec[x].push_back(node(i,y));
fa[i]=x; flen[i]=y;
}
init();
dfs(1);//从根节点向下搜的
// repf(i,1,n) cout<<len[i]<<" "<<len2[i]<<" "<<nod[i]<<endl;
repf(i,1,n)
dp[i]=len[i];//从子节点引申出来的
repf(i,1,n)
dp[i]=max(dp[i],find(i,-1));
repf(i,1,n)
printf("%d\n",dp[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: