树的中心
题意:找一个点,使得他到其他点的最长距离最小,边权有正有负。
如果我们将这颗树化为一个有根树,那么一个点到其他点的最远距离就是: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 }