hdu2196 树形DP

来源:互联网 发布:js random 编辑:程序博客网 时间:2024/05/29 17:57
题意:
      给你一棵树,求出每一个点到其他点的最大距离.

思路:

      每个点的最大距离只有两种情况,1是自己忘下面走的最大,二是网上走的最大,取他们的最大便是答案,每个点网下面的最大可以空过dfs直接在回溯的时候求出来,但网上走的呢?往上走其实就是他父亲往上走的最大 和 他父亲往下走最大 中大的那个加上他和她父亲的距离得到的,但是他父亲往下走的最大有可能是他这条路,就是路过他,那么怎么办呢,我们可以再第一遍dfs求最大的时候求出个次大,第二大,当最大的路路过他时那么直接用次大的代替最大,就这样树形dp一边,得到自己网上走的最大,然后输出自己网上走最大和往下走最大中的最优值就行了,具体看代码就懂了,第一遍深搜从下网上,第二遍从上往下...据说还可以用树的直径的性质做,求出树的直径,然后输出max(dis[s] ,dis[t]);自己没试验行不行,不知道时间能不能超时,如果超时我感觉可以用LCA去优化...



#include<stdio.h>#include<string.h>#define N 11000                                     typedef struct{   int to ,next ,cost;}STAR;STAR E[N];int list[N] ,tot;int maxz[N] ,maxc[N];int dp[N] ,mer[N];void add(int a ,int b ,int c){   E[++tot].to = b;   E[tot].cost = c;   E[tot].next = list[a];   list[a] = tot;}int maxx(int a ,int b){             return a > b ? a : b;}void DFS1(int s){   int maz = 0 ,mac = 0 ,mk = 0;   for(int k = list[s] ;k ;k = E[k].next)   {      int to = E[k].to;      mk =  1;      DFS1(to);      if(maz <  maxz[to] + E[k].cost)      {                                 mer[s] = to;         mac = maz;         maz = maxz[to] + E[k].cost;      }       else      mac = maxx(mac ,maxz[to] + E[k].cost);   }   if(mk)   {      maxz[s] = maz;      maxc[s] = mac;   }   else maxz[s] = maxc[s] = 0;}void DFS2(int s){   for(int k = list[s] ;k ; k = E[k].next)   {      int to = E[k].to;      if(to == mer[s])      dp[to] = maxx(dp[s] ,maxc[s]) + E[k].cost;      else      dp[to] = maxx(dp[s] ,maxz[s]) + E[k].cost;      DFS2(to);   }}int main (){   int  n ,i ,a ,b;   while(~scanf("%d" ,&n))   {      memset(list ,0 ,sizeof(list));      tot = 1;      for(i = 2 ;i <= n ;i ++)      {         scanf("%d %d" ,&a ,&b);         add(a ,i ,b);      }      DFS1(1);      dp[1] = 0;      DFS2(1);            for(i = 1 ;i <= n ;i ++)      printf("%d\n" ,maxx(maxz[i] ,dp[i]));   }   return 0;}               

0 0
原创粉丝点击