Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2679 Accepted Submission(s):
1373
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.
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
提供两组数据先:
5
1 2
2 3
2 4
2 1
answer:6 4 7 7 5
8
5 3
5 3
6 2
1 3
5 4
6 1
6 7
answer: 14 14 14 9 11 7 8 14
题意:求一棵树中,任一点到树中所有点的最长距离。
思路:对于每个节点,保存两个值。
dp[k][0]距离该点,最长的距离。
dp[k][1]距离该点,此长的距离。但是不能理解成dp[k][1]一定小于dp[k][0];
这里的次长的意思,保存 到该节点的距离排序中的第二大的值。出现多个相等,则dp[k][0]==dp[k][1];
首选树形dp一次,求出离根节点最远的距离是可以的。当然,我们不能枚举离每个节点为根节点的情况。
但是,我们还需要一次搜索。
这一次的搜索,更新给个节点的dp[t][0],dp[t][1]的值。
以根节点root为例。
root的所以子节点都保存了dp[t][0],dp[t][1]的值。此时,更新某一个儿子节点.
如果到达root的最大值,就是经过这个儿子节点的,那么,就让它加上次长的值,来判断更新,
如果不是经过这个儿子节点,那么就用dp[root][0]来更新。
1 #include<iostream> 2 #include<stdio.h> 3 #include<vector> 4 #include<cstring> 5 #include<cstdlib> 6 #include<algorithm> 7 #include<queue> 8 using namespace std; 9 10 vector<int>Q[10002]; 11 vector<int>val[10002]; 12 queue<int>H; 13 bool use[10002]; 14 int num[10002]; 15 int dp[10002][2]; 16 int hxl[10002],hlen,flag; 17 18 void add(int x,int y,int len) 19 { 20 Q[x].push_back(y); 21 val[x].push_back(len); 22 num[x]++; 23 } 24 int Max(int x,int y) 25 { 26 return x>y? x:y; 27 } 28 void dfs(int k) 29 { 30 int i,t,cur=0; 31 use[k]=true; 32 for(i=0;i<num[k];i++) 33 { 34 t=Q[k][i]; 35 if(use[t]==true) continue; 36 dfs(t); 37 if( dp[k][0]<=dp[t][0]+val[k][i])//更新dp[k][0]; 38 { 39 dp[k][1]=dp[k][0];//覆盖给dp[k][1]; 40 dp[k][0]=dp[t][0]+val[k][i]; 41 } 42 else if( dp[k][1]<dp[t][0]+val[k][i] )//这个不能少,虽然比第一个小,但是可能比dp[k][1]大呀。 43 { 44 dp[k][1]=dp[t][0]+val[k][i]; 45 } 46 } 47 } 48 void bfs(int n) 49 { 50 int k,t,i,tmp; 51 H.push(n); 52 use[n]=true; 53 while(!H.empty()) 54 { 55 k=H.front(); 56 H.pop(); 57 for(i=0;i<num[k];i++) 58 { 59 t=Q[k][i]; 60 if(use[t]==true) continue; 61 use[t]=true; 62 if(dp[t][0] == dp[k][0]-val[k][i])//判断是来自该条路。 63 { 64 tmp=dp[k][1]+val[k][i];//用dp[k][1]次长来更新dp[t][1] , dp[t][0]; 65 if(dp[t][0]<=tmp) 66 { 67 dp[t][1]=dp[t][0]; 68 dp[t][0]=tmp; 69 } 70 else if(dp[t][1]<tmp) 71 dp[t][1]=tmp; 72 } 73 else //dp[k][0]不是经过该节点的 74 { 75 dp[t][1]=dp[t][0];//覆盖 76 dp[t][0]=dp[k][0]+val[k][i];//此时就直接赋值了。 77 } 78 H.push(t); 79 } 80 } 81 } 82 void solve(int n) 83 { 84 int i; 85 dfs(1); 86 if(hlen==1) hxl[++hlen]=0; 87 sort(hxl+1,hxl+1+hlen); 88 memset(use,false,sizeof(use)); 89 bfs(1); 90 for(i=1;i<=n;i++) 91 printf("%d ",dp[i][0]); 92 } 93 int main() 94 { 95 int n,i,x,length; 96 while(scanf("%d",&n)>0) 97 { 98 for(i=0;i<=n;i++) 99 { 100 Q[i].clear(); 101 val[i].clear(); 102 } 103 memset(dp,0,sizeof(dp)); 104 memset(use,false,sizeof(use)); 105 memset(num,0,sizeof(num)); 106 memset(hxl,0,sizeof(hxl)); 107 for(i=2;i<=n;i++) 108 { 109 scanf("%d%d",&x,&length); 110 add(i,x,length); 111 add(x,i,length); 112 } 113 hlen=0; 114 flag=-1; 115 solve(n); 116 } 117 return 0; 118 }