树的中心

题意:找一个点,使得他到其他点的最长距离最小,边权有正有负。

如果我们将这颗树化为一个有根树,那么一个点到其他点的最远距离就是:MAX(他到子树某个点的最远距离,他经过父亲节点到其他的点的最远距离)。
第一部分可以直接一次dfs得到,对于第二部分来说可以再次dfs维护数组F[u],表示u经过父节点到其他节点的最远距离,由于他可能通过父节点走回自己(父节点到当前节点距离最远),故在第一次dfs时候需要维护一个次大值,并且维护当前点是否在最长路径中。
————————————————
版权声明:本文为CSDN博主「cy41」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chenyume/article/details/102941711

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn=1e4+7;
 5 vector<pair<int,int> > G[maxn];
 6 
 7 void add(int u,int v,int w){
 8     G[u].push_back({v,w});
 9     G[v].push_back({u,w});
10 }
11 
12 int FMax[maxn],SMax[maxn],neber[maxn];
13 int Up[maxn];
14 const int inf=0x3f3f3f3f;
15 void dfs(int u,int fa){
16     FMax[u]=SMax[u]=-inf;
17     for(auto p:G[u]){
18         int v=p.first,w=p.second;
19         if(v==fa) continue;
20         dfs(v,u);
21         int val=FMax[v]+w;
22         if(val>=FMax[u]){
23             SMax[u]=FMax[u];
24             FMax[u]=val;
25             neber[u]=v;
26         }
27         else SMax[u]=max(SMax[u],val);
28     }
29     if(FMax[u]==-inf) FMax[u]=SMax[u]=0;
30 }
31 
32 void Dfs(int u,int fa){
33     for(auto p:G[u]){
34         int v=p.first,w=p.second;
35         if(v==fa) continue;
36         if(neber[u]==v) Up[v]=max(Up[u],SMax[u])+w;
37         else Up[v]=max(Up[u],FMax[u])+w;
38         Dfs(v,u);
39     }
40 }
41 int main(){
42     int n,u,v,w;
43     scanf("%d",&n);
44     for(int i=1;i<n;++i){
45         scanf("%d%d%d",&u,&v,&w);
46         add(u,v,w);
47     }
48     dfs(1,0);
49     Dfs(1,0);
50     int res=inf;
51     for(int i=1;i<=n;++i) res=min(res,max(Up[i],FMax[i]));
52     printf("%d\n",res);
53 
54     return 0;
55 }

 

posted @ 2020-03-09 22:28  古比  阅读(455)  评论(0)    收藏  举报