最近两天在研究树形dp,很是郁闷啊!!

今天终于完完整整的写出来一道了(一次AC),不过还是上网搜的报告,虽然如此,还是值得庆贺的~

分析:

/*两次遍历整棵树,一次从叶子到树根,求得以该点为根的树中节

点到该点的最远距离,第二次从根到叶子进行遍历,因为每一个点到

其它点的最远距离不一定在以该点为根的树中,可能在父节点的其它分

支中,因此可以更新父节点到当前点的最远距离,然后比较每条分支的

远距离即可求得当前点的最远距离,这样便可以求出最后结果

*/

代码:

 1 # include<stdio.h>
2 # include<string.h>
3 # define N 10005
4 struct node{
5 int from,to,next,val,val1;
6 }edge[2*N];//用邻接表进行存储
7 int head[N],tol,visit[N],h[N],w[N],dp[N];
8 int n;
9 void add(int a,int b,int c)
10 {
11 edge[tol].from=a;edge[tol].to=b;edge[tol].val=c;edge[tol].next=head[a];head[a]=tol++;
12 }
13 int max(int a,int b)
14 {
15 return a>b?a:b;
16 }
17 void dfs(int root)
18 {
19 int j,u;
20 visit[root]=1;
21 for(j=head[root];j!=-1;j=edge[j].next)
22 {
23 u=edge[j].to;
24 if(!visit[u])
25 {
26 dfs(u);
27 dp[root]=max(dp[root],dp[u]+edge[j].val);
28 edge[j].val1=dp[u]+edge[j].val;//父亲节点在该分支上的最远距离
29 }
30 }
31 }
32 void dfs1(int root,int son,int k)
33 {
34 int j,res=0,u;
35 visit[son]=1;
36 for(j=head[root];j!=-1;j=edge[j].next)
37 {
38 u=edge[j].to;
39 if(u!=son) res=max(res,edge[j].val1);//父亲节点的其他分支到父亲节点的最远距离
40 }
41 w[son]=max(w[root]+edge[k].val,res+edge[k].val);//该点 以上 到该点的最远距离
42 dp[son]=max(w[son],dp[son]);
43 for(j=head[son];j!=-1;j=edge[j].next)
44 {
45 u=edge[j].to;
46 if(!visit[u])
47 {
48 dfs1(son,u,j);
49 }
50 }
51 }
52 int main()
53 {
54 int i,j,x1,x2;
55 while(scanf("%d",&n)!=EOF)
56 {
57 tol=0;
58 memset(head,-1,sizeof(head));
59 for(i=1;i<n;i++)
60 {
61 scanf("%d%d",&x1,&x2);
62 add(x1,i+1,x2);//建边
63 add(i+1,x1,x2);
64 }
65 memset(visit,0,sizeof(visit));
66 memset(dp,0,sizeof(dp));//以该点为根的树中节点到该点的最远距离
67 dfs(1);
68 memset(visit,0,sizeof(visit));
69 memset(w,0,sizeof(w));//父亲节点的其他分支到该点的最远距离
70 visit[1]=1;
71 w[1]=0;
72 for(j=head[1];j!=-1;j=edge[j].next)
73 {
74 dfs1(1,edge[j].to,j);
75 }
76 for(i=1;i<=n;i++)
77 printf("%d\n",dp[i]);
78 }
79 return 0;
80 }
posted on 2011-07-19 16:52  奋斗青春  阅读(1118)  评论(0编辑  收藏  举报