题意+题解:
1 //5 2 //1 1 3 //2 1 4 //3 1 5 //1 1 6 //给你5个点,从下面第二行到第五行(称为i行),每一行两个数x,y。表示i和x之间有一条边。这一条边的长度为y 7 //你需要找出来每一个点与所有点相距的最大值。并且在最后输出。 8 //要注意这是一棵树,为什么这样说呢。因为你只有n-1条边,而且每一个点都至少有一条边 9 10 //这样的话我们可以用bfs找出来随意一个点x距离其他点的距离。然后找到其中那个与x相距最大的点x1,再用他去跑一遍bfs 11 //再找出来距离这个点x1相距最大的点x2。再跑一遍bfs。让这些距离取最大值输出就可以了 12 // 13 //因为你第一次找到的那个点肯定是图的深度最深的叶节点x1。在用这个x1找另一个叶节点x2,其他点与与所有点的最大距离肯定 14 //在这两个点之间。。因为这两个点就是深度最大的 15 #include<stdio.h> 16 #include<string.h> 17 #include<iostream> 18 #include<algorithm> 19 #include<queue> 20 using namespace std; 21 const int maxn=20010; 22 int cnt,head[maxn],deap1[maxn],vis[maxn],deap2[maxn],n,deap3[maxn]; 23 queue<int>r; 24 struct edge 25 { 26 int u,v,next,w; 27 }e[maxn]; 28 void init(int deap[maxn]) 29 { 30 for(int i=1;i<=n;++i) 31 deap[i]=0; 32 } 33 void add_edge(int x,int y,int z) 34 { 35 e[cnt].u=x; 36 e[cnt].v=y; 37 e[cnt].w=z; 38 e[cnt].next=head[x]; 39 head[x]=cnt++; 40 } 41 void bfs(int x,int deap[maxn]) 42 { 43 while(!r.empty()) r.pop(); 44 init(vis); 45 vis[x]=1; 46 r.push(x); 47 while(!r.empty()) 48 { 49 int u=r.front(); 50 r.pop(); 51 for(int i=head[u];i!=-1;i=e[i].next) 52 { 53 int v=e[i].v; 54 if(!vis[v]) 55 { 56 vis[v]=1; 57 deap[v]=deap[u]+e[i].w; 58 r.push(v); 59 } 60 } 61 } 62 } 63 int main() 64 { 65 while(~scanf("%d",&n)) 66 { 67 memset(head,-1,sizeof(head)); 68 cnt=0; 69 for(int i=2;i<=n;++i) 70 { 71 int x,y; 72 scanf("%d%d",&x,&y); 73 add_edge(i,x,y); 74 add_edge(x,i,y); 75 } 76 init(deap1); 77 bfs(1,deap1); 78 int ans1=0,id1=-1;//printf("** "); 79 for(int i=1;i<=n;++i) 80 { 81 if(ans1<deap1[i]) 82 { 83 ans1=deap1[i]; 84 id1=i; 85 } 86 } 87 init(deap2); 88 if(id1!=-1) 89 { 90 bfs(id1,deap2); 91 } 92 ans1=0,id1=-1; 93 for(int i=1;i<=n;++i) 94 { 95 if(ans1<deap2[i]) 96 { 97 ans1=deap2[i]; 98 id1=i; 99 } 100 } 101 init(deap3); 102 if(id1!=-1) 103 { 104 bfs(id1,deap3); 105 } 106 for(int i=1;i<=n;++i) 107 { 108 printf("%d ",max(deap1[i],max(deap2[i],deap3[i]))); 109 } 110 } 111 return 0; 112 }