Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6225 Accepted Submission(s):
3142
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
题目大意:给你一n个节点n-1条边无环图(其实是树),请问对于每个节点与其他节点的最远距离是多少
对于每个节点来说,它的最远距离只有两种可能,就是:
1.来自它的子树。
2.来自它的父节点。
因此我们要做两遍dfs
第一遍:得出每个节点来自子树的最短,次短距离(求次短是为了在避免第二次dfs时该节点的父节点的极大值就来自该子节点导致比对无意义)
第二遍:得出来来自父节点最短。
#include<cstdio> #include<cstring> #include<algorithm> #define N 10005 using namespace std; struct X { int v,q,f,n; }x[N]; int n,m,f[N][3];//f[i][0]表示从子树最大,f[i][1]表示次大,f[i][2]表示从父节点最大 void dfs1(int u) { for(int i=x[u].f;i;i=x[i].n) { dfs1(x[i].v); if(f[x[i].v][0]+x[i].q>f[u][0]) { f[u][1]=f[u][0]; f[u][0]=f[x[i].v][0]+x[i].q; } else if(f[u][1]<f[x[i].v][0]+x[i].q) f[u][1]=f[x[i].v][0]+x[i].q; } } void dfs2(int u) { for(int i=x[u].f;i;i=x[i].n) { f[x[i].v][2]=x[i].q+max(f[u][2],f[x[i].v][0]+x[i].q==f[u][0]?f[u][1]:f[u][0]); dfs2(x[i].v); } } int main() { while(scanf("%d",&n)!=EOF) { memset(x,0,sizeof(x)); memset(f,0,sizeof(f)); for(int i=1;i<n;i++) { int u; scanf("%d%d",&u,&x[i].q); x[i].v=i+1; x[i].n=x[u].f; x[u].f=i; } dfs1(1); dfs2(1); for(int i=1;i<=n;i++) printf("%d\n",max(f[i][0],f[i][2]));//两种比较取最大 } return 0; }