hdu 2196
树形dp题,要求求出书上的最远距离;
很经典的一种树形dp;
思路:最远距离要么是从老爸的最远距离+自己与老爸的距离;
要么是儿子的最远距离+自己与儿子的距离;
然后比较上面两个的大小就是答案了!
参考了别人的代码:
两次搜索:
1.第一次搜索是从下至上的搜索,找到每个节点的最远距离f[],次远距离sf[];并记录最远距离的那个点;
2.第二次搜索是从上往下的搜索,找到老爸那边来的最远距离dp[];
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #define maxn 10005 5 using namespace std; 6 7 struct node 8 { 9 int v,w; 10 }; 11 12 vector<node>ve[maxn]; 13 int dp[maxn],f[maxn],d[maxn],sf[maxn]; 14 15 void dfs1(int a) 16 { 17 int f1=-1,f2=-1,max=-1; 18 int l=ve[a].size(); 19 if(f[a]||l==0)return; 20 for(int i=0; i<l; i++) 21 { 22 int k=ve[a][i].v; 23 dfs1(k); 24 if(max<f[k]+ve[a][i].w) 25 { 26 max=f[k]+ve[a][i].w; 27 f1=i; 28 } 29 } 30 d[a]=f1; 31 f[a]=max; 32 max=-1; 33 for(int i=0;i<l;i++) 34 { 35 int k=ve[a][i].v; 36 if(i!=f1&&max<f[k]+ve[a][i].w) 37 { 38 max=f[k]+ve[a][i].w; 39 f2=i; 40 } 41 } 42 if(f2!=-1) sf[a]=max; 43 } 44 45 void dfs2(int a) 46 { 47 int l=ve[a].size(); 48 if(l==0)return; 49 for(int i=0;i<l;i++) 50 { 51 int k=ve[a][i].v; 52 if(i==d[a]) 53 dp[k]=max(sf[a],dp[a])+ve[a][i].w; 54 else dp[k]=max(f[a],dp[a])+ve[a][i].w; 55 dfs2(k); 56 } 57 } 58 59 int main() 60 { 61 int n,a,b; 62 node no; 63 while(scanf("%d",&n)!=EOF) 64 { 65 for(int i=1; i<=n; i++) 66 ve[i].clear(); 67 memset(dp,0,sizeof dp); 68 memset(f,0,sizeof f); 69 memset(d,0,sizeof d); 70 memset(sf,0,sizeof sf); 71 for(int i=2; i<=n; i++) 72 { 73 scanf("%d%d",&a,&b); 74 no.v=i; 75 no.w=b; 76 ve[a].push_back(no); 77 } 78 dfs1(1); 79 dfs2(1); 80 for(int i=1; i<=n; i++) 81 printf("%d\n",max(dp[i],f[i])); 82 } 83 return 0; 84 }