hdu 2196 Computer
Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2361 Accepted Submission(s): 1207
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
Recommend
lcy
1 //31MS 960K 1817 B C++ 2 /* 3 (转) 4 经典的树形DP: 5 6 这里用了两次的bfs。 7 第一次是自上而下地求出每个节点的的最长距离f[i], 8 同时,求出在第二次bfs 要用的次长度g[i]。 9 自己画图可以知道,一个点的最长距离只可能是由它的 10 子节点得到,或者从它的父结点的最长距离或者次长距离加上 11 它与父节点的距离得到。从这里我们就可以得到状态转移方程。 12 而且节点的最长距离就是f[i],h[i] 中的最大值。 13 14 f[i]表示以节点 i 向其 子树搜索 所能到达的最远距离 15 g[i]表示次远距离 16 longest[i]记录 到达最远距离的那条边(最远 和次远 不会重边:最长距离来自子节点中的一个,故不会重边) 17 h[i]表示 节点i 经其父亲节点延伸(延伸到父亲的最长或着次长), 18 所能到达的最远距离 19 求 i的最远时, i可能在父亲的最长路径上,也可能不再, 20 所以要记录最远 可能是向上最远 也可能向下 21 所以最后要 max(f[k],dp[k]); 22 23 */ 24 #include<iostream> 25 #include<vector> 26 #define N 10005 27 using namespace std; 28 vector<int>son[N],w[N]; //存放子节点和每个节点的权值 29 int f[N]; //每个节点到叶子节点的最长距离 30 int g[N]; //次长度 31 int longest[N]; //最长距离对应的序号 32 int h[N]; //每个节点到父亲节点最长距离 33 int n; 34 void init() 35 { 36 memset(f,0,sizeof(f)); 37 memset(g,0,sizeof(g)); 38 memset(longest,0,sizeof(longest)); 39 memset(h,0,sizeof(h)); 40 for(int i=0;i<=n;i++){ 41 son[i].clear(); 42 w[i].clear(); 43 } 44 } 45 //求节点v往下到叶子节点的最长距离 46 int dfs1(int x) 47 { 48 int flag; //标记最长距离序号 49 if(f[x]) return f[x]; 50 int m=son[x].size(); 51 if(m==0) return 0; 52 for(int i=0;i<m;i++){ 53 int temp=son[x][i]; 54 dfs1(temp); //dfs处理由下往上递推 55 if(f[temp]+w[x][i]>f[x]){ //更新最长距离 56 g[x]=f[x]; 57 f[x]=f[temp]+w[x][i]; 58 flag=temp; 59 } 60 else if(f[temp]+w[x][i]>g[x]){ //更新次长距离 61 g[x]=f[temp]+w[x][i]; 62 } 63 } 64 longest[x]=flag; 65 return f[x]; 66 } 67 //求出h[i],记录父节点与其的最长距离 68 void dfs2(int x) 69 { 70 int m=son[x].size(); 71 for(int i=0;i<m;i++){ 72 int temp=son[x][i]; 73 if(temp==longest[x]) //最长距离经过该点 74 h[temp]=max(h[x],g[x])+w[x][i]; 75 else h[temp]=max(h[x],f[x])+w[x][i]; 76 dfs2(temp); //更新子节点 77 } 78 } 79 int main(void) 80 { 81 int a,b; 82 while(scanf("%d",&n)!=EOF) 83 { 84 init(); 85 for(int i=2;i<=n;i++){ 86 scanf("%d%d",&a,&b); 87 son[a].push_back(i); 88 w[a].push_back(b); 89 } 90 dfs1(1); 91 dfs2(1); 92 for(int i=1;i<=n;i++){ 93 printf("%d\n",max(f[i],h[i])); 94 } 95 } 96 return 0; 97 }
另附小菜的代码:
1 //31MS 740K 1495 B C++ 2 #include<iostream> 3 #include<vector> 4 #define N 10005 5 using namespace std; 6 struct node{ 7 int v; 8 int len; 9 node(int a,int b){ 10 v=a;len=b; 11 } 12 }; 13 vector<node>V[N]; 14 int f[N]; 15 int g[N]; 16 int l[N]; 17 int h[N]; 18 int n; 19 void init() 20 { 21 memset(f,0,sizeof(f)); 22 memset(g,0,sizeof(g)); 23 memset(l,0,sizeof(l)); 24 memset(h,0,sizeof(h)); 25 for(int i=0;i<=n;i++) 26 V[i].clear(); 27 } 28 int dfs1(int x) 29 { 30 int flag=-1; 31 if(f[x]) return f[x]; 32 int m=V[x].size(); 33 if(m==0) return 0; 34 for(int i=0;i<m;i++){ 35 int temp=V[x][i].v; 36 dfs1(temp); 37 if(f[temp]+V[x][i].len>f[x]){ 38 g[x]=f[x]; 39 f[x]=f[temp]+V[x][i].len; 40 flag=temp; 41 }else if(f[temp]+V[x][i].len>g[x]) 42 g[x]=f[temp]+V[x][i].len; 43 } 44 l[x]=flag; 45 return f[x]; 46 } 47 void dfs2(int x) 48 { 49 int m=V[x].size(); 50 for(int i=0;i<m;i++){ 51 int temp=V[x][i].v; 52 if(temp==l[x]){ 53 h[temp]=max(h[x],g[x])+V[x][i].len; 54 }else{ 55 h[temp]=max(h[x],f[x])+V[x][i].len; 56 } 57 dfs2(temp); 58 } 59 } 60 int main(void) 61 { 62 int a,b; 63 while(scanf("%d",&n)!=EOF) 64 { 65 init(); 66 for(int i=2;i<=n;i++){ 67 scanf("%d%d",&a,&b); 68 V[a].push_back(node(i,b)); 69 } 70 dfs1(1); 71 dfs2(1); 72 for(int i=1;i<=n;i++) 73 printf("%d\n",max(f[i],h[i])); 74 } 75 return 0; 76 }