JZOJ 树形dp练习6-树的直径(树形dp入门)

来源:JZOJ

题目描述

给定 1 1 n n 个点的边权树,让你求树的直径

解题思路

  • 这题和树形dp练习4差不多,只是在 d f s dfs 中的一个细节上做了一个小改动;其实,树的最长路径可以由最长链+次长链得到,这样就简单明了了

代码君

#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;
}
发布了27 篇原创文章 · 获赞 33 · 访问量 1674

猜你喜欢

转载自blog.csdn.net/qq_43081996/article/details/104210111