題意: 求每一個點的最遠距離。ios
樹形dp,作了兩天,感受就是從子節點獲得父節點。數組
此題要用到兩次dfs, 第一次dfs1用來求全部節點在他子樹範圍內到葉子節點的最長距離和次長距離。dp1,和dp2ide
第二次dfs2 ,求f【】,若是dp1[s]==dp1[x]+len (s爲父節點,x爲子節點),則 x 在最長樹的分支上,f[x]=max(f[s]+len,dp2[s]+len); spa
因此f【x】就等於f父節點加上到子節點的距離和父節點的次長加上到x節點的距離的二者的最大值。code
若是 不相等,則表明x節點不在父節點最長的分支上。則f【x】就等於f父節點到x節點的距離和父節點的最長距離加上到子節點距離 二者的最大值。blog
結果在max(f【】,dp1【】)string
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<iostream> 5 using namespace std; 6 const int Max=10001; 7 struct Point 8 { 9 int v,w; 10 }; 11 vector<Point>V[Max]; 12 int vis[Max]; 13 int f[Max],dp1[Max],dp2[Max]; 14 void init() 15 { 16 for(int i=1;i<Max;i++) 17 { 18 V[i].clear(); 19 } 20 memset(dp1,0,sizeof(dp1)); 21 memset(dp2,0,sizeof(dp2)); 22 memset(vis,0,sizeof(vis)); 23 memset(f,0,sizeof(f)); 24 } 25 void dfs1(int s) //全部節點在他子樹範圍內到葉子節點的最長距離和次長距離。dp1,和dp2 26 { 27 vis[s]=1; 28 for(int i=0;i<(int)V[s].size();i++) 29 { 30 int x=V[s][i].v; 31 int len=V[s][i].w; 32 if(!vis[x]) 33 { 34 dfs1(x); 35 int a=max(max(dp1[s],dp2[s]),dp1[x]+len); 36 if(a==dp1[s]) dp2[s]=max(dp2[s],dp1[x]+len); 37 else if(a==dp2[s]) dp2[s]=max(dp1[s],dp1[x]+len); 38 else dp2[s]=max(dp1[s],dp2[s]); 39 dp1[s]=a; 40 } 41 } 42 } 43 void dfs2(int s) //第二次dfs,求f數組。 44 { 45 vis[s]=1; 46 for(int i=0;i<(int)V[s].size();i++) 47 { 48 int x=V[s][i].v; 49 int len=V[s][i].w; 50 if(!vis[x]) 51 { 52 if(dp1[s]==dp1[x]+len) 53 f[x]=max(f[s]+len,dp2[s]+len); 54 else 55 f[x]=max(f[s]+len,dp1[s]+len); 56 dfs2(x); 57 } 58 } 59 } 60 int main() 61 { 62 //freopen("Input.txt","r",stdin); 63 int n,i; 64 while(~scanf("%d",&n)) 65 { 66 init(); 67 int a,b; 68 for(i=2;i<=n;i++) 69 { 70 scanf("%d%d",&a,&b); 71 Point tmp; 72 tmp.v=a;tmp.w=b; 73 V[i].push_back(tmp); 74 tmp.v=i; 75 V[a].push_back(tmp); 76 } 77 dfs1(1); 78 memset(vis,0,sizeof(vis)); 79 dfs2(1); 80 for(i=1;i<=n;i++) 81 printf("%d\n",max(dp1[i],f[i])); 82 } 83 return 0; 84 }