来源:JZOJ
题目描述
给定 棵 个点的边权树,让你求树的直径
解题思路
- 这题和树形dp练习4差不多,只是在 中的一个细节上做了一个小改动;其实,树的最长路径可以由最长链+次长链得到,这样就简单明了了
代码君
#include <bits/stdc++.h>
using namespace std;
long long dis[200010],dis2[200010];
int t=0,n,linkk[200010];
long long ans=-0xfffffff;
struct node
{
int y,v,next;
}e[200010];
void insert(int x,int y,int v)
{
e[++t].y=y; e[t].v=v;
e[t].next=linkk[x]; linkk[x]=t;
}
void dfs(int x,int father)
{
for (int i=linkk[x];i;i=e[i].next)
{
int y=e[i].y;
if (y!=father)
{
dfs(y,x);
if(dis[y]+e[i].v>dis[x]) //更新最长链
{
dis2[x]=dis[x];
dis[x]=dis[y]+e[i].v;
}
else
if(dis[y]+e[i].v<dis[x] && dis[y]+e[i].v>dis2[x]) //更新次长链
dis2[x]=dis[y]+e[i].v;
}
}
ans=max(ans,dis[x]+dis2[x]);
}
int main()
{
freopen("treediam.in","r",stdin);
freopen("treediam.out","w",stdout);
memset(dis,0,sizeof(dis));
memset(dis2,0,sizeof(dis2));
memset(linkk,0,sizeof(linkk));
t=0;
scanf("%d",&n);
for (int i=1;i<n;i++)
{
int x,y,v;
scanf("%d %d %d",&x,&y,&v);
insert(x,y,v); //邻接表插入
insert(y,x,v);
}
dfs(1,0);
printf("%d",ans);
return 0;
}