1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std;
const int N=10010; struct edge { int go,v,next; }; edge eg[2*N]; int last[N],fm[N],sm[N]; //fm[] first max 记儿子、孙子等到该节点的最远路 sm[] 次远路 //当然,这两个值不能来自于同一个子树,因为不能重复经过结点 int tot=0;
void add(int x,int y,int z) { eg[++tot].go=y; eg[tot].v=z; eg[tot].next=last[x]; last[x]=tot; }
void dfs(int x,int fa) { if (last[x]==0) return; int p=0,q=0,i; for (i=last[x];i;i=eg[i].next) { int u=eg[i].go; if (u==fa) continue; dfs(u,x); if (eg[i].v+fm[u]>p) { q=p; p=eg[i].v+fm[u]; } else if (eg[i].v+fm[u]>q) q=eg[i].v+fm[u]; } fm[x]=p;sm[x]=q; }
int main() { int n,i,x,y,z,ans; scanf("%d",&n); for (i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } dfs(1,0); ans=-1; for (i=1;i<=n;i++) ans=max(ans,fm[i]+sm[i]); printf("%d\n",ans*(ans+1)/2+ans*10); return 0; }
|