HDU-2196-树形dp/计算树上固定起点的最长路

Computer

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32263    Accepted Submission(s): 4472


Problem Description
A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information. 


Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
 
Input
Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.
 
Output
For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).
 
Sample Input
5 1 1 2 1 3 1 1 1
 
Sample Output
3 2 3 4 4
 
Author
scnu
        给出一棵树,边上有权值,计算树上每个顶点以自己为起点可以走的最长的路径长度。
        经典的树dp,这条最长路径可能是向下走也可能是想自己的父亲走来达到,我们先dfs1计算出所有点向下走达到的最长路径和次长路径,并记录走向的是哪个儿子。然后在dfs2里计算向上走的最长路径,与已知的两条作比较选出最优的。
     记录次长路径的必要性在于父亲的最长路可能就是走向的当前的节点,这样显然不能走重边,如果我们有父亲的次长路(存在的话),那么一定能沿着父亲回去。
     很少写这种,想了一下午总算1A了。
       
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long 
 4 #define pii pair<int,int>
 5 #define mp make_pair
 6 const int MAXN=10006;
 7 int fm[MAXN],sm[MAXN];
 8 int fid[MAXN],sid[MAXN];
 9 vector<pii>g[10005];
10 int N;
11 void dfs1(int u,int fa)
12 {
13     fm[u]=sm[u]=0;
14     fid[u]=sid[u]=0;
15     for(int i=0;i<g[u].size();++i){
16         int v=g[u][i].first;
17         int w=g[u][i].second;
18         if(v==fa) continue;
19         dfs1(v,u);
20         if(fm[v]+w>sm[u]){
21             sm[u]=fm[v]+w;
22             sid[u]=v;
23             if(sm[u]>fm[u]){
24                 swap(fm[u],sm[u]);
25                 swap(fid[u],sid[u]);
26             }
27         }
28     }
29 }
30 void dfs2(int u,int fa,int w)
31 {
32     if(fm[fa]+w>sm[u]&&fid[fa]!=u){
33             sm[u]=fm[fa]+w;
34             sid[u]=fa;
35             if(sm[u]>fm[u]){
36                 swap(fm[u],sm[u]);
37                 swap(fid[u],sid[u]);
38             }
39         }
40         if(sm[fa]+w>sm[u]&&sid[fa]!=u){
41             sm[u]=sm[fa]+w;
42             sid[u]=fa;
43             if(sm[u]>fm[u]){
44                 swap(fm[u],sm[u]);
45                 swap(fid[u],sid[u]);
46             }
47         }
48     for(int i=0;i<g[u].size();++i){
49         int v=g[u][i].first;
50         int ww=g[u][i].second;
51         if(v==fa) continue;
52         dfs2(v,u,ww);
53     }
54 }
55 int main()
56 {
57     while(cin>>N){int u,v,w;
58         for(int i=2;i<=N;++i){
59             scanf("%d%d",&v,&w);
60             g[i].push_back(mp(v,w));
61             g[v].push_back(mp(i,w));
62         }
63         dfs1(1,0);
64         /*for(int i=1;i<=N;++i)
65         cout<<fm[i]<<' '<<fid[i]<<' '<<sm[i]<<' '<<sid[i]<<endl;*/
66         dfs2(1,0,0);
67         for(int i=1;i<=N;++i) printf("%d
",max(fm[i],sm[i]));
68         for(int i=1;i<=N;++i)g[i].clear();
69     }
70     return 0;
71 }
72 
73 /*
74 3 2 1 5
75 2 3 0 0
76 1 4 0 0
77 0 0 0 0
78 0 0 0 0
79 */
原文地址:https://www.cnblogs.com/zzqc/p/8847765.html