hdu 3534 (树形DP)

题意:求出树的最长边和个数。

思路:最长边以前做过,用树形DP可以。求最长边的时候可以统计一下最长边的个数,那么以u为根节点的子树中最长边为:Len[u]+max(len[v]),个数node[u]*node[v]。






#include<stdio.h>
#include<string.h>
const int N=500000;
const int inf=0x3fffffff;
int head[N],num,Len[N],ans,node[N],k;
struct edge
{
	int ed,w,next;
}e[N*2];
void addedge(int x,int y,int w)
{
	e[num].ed=y;e[num].w=w;e[num].next=head[x];head[x]=num++;
	e[num].ed=x;e[num].w=w;e[num].next=head[y];head[y]=num++;
}
void dfs(int u,int fa)
{
	int i,v,temp;
	Len[u]=0;//最长边
	node[u]=1;//最长边的个数
	for(i=head[u];i!=-1;i=e[i].next)
	{
		v=e[i].ed;
		if(v==fa)continue;
		dfs(v,u);
		temp=Len[v]+e[i].w;
		if(temp+Len[u]>ans)//最长边经过v
		{
			k=node[v]*node[u];
			ans=temp+Len[u];
		}
		else if(temp+Len[u]==ans)
			k+=node[v]*node[u];
		if(Len[u]<temp)//更新最长边
		{
			Len[u]=temp;
			node[u]=node[v];
		}
		else if(Len[u]==temp)//更新最长边的个数
			node[u]+=node[v];
	}
}
int main()
{
	int n,i,x,y,w;
	while(scanf("%d",&n)!=-1)
	{
		memset(head,-1,sizeof(head));
		num=0;
		for(i=1;i<n;i++)
		{
			scanf("%d%d%d",&x,&y,&w);
			addedge(x,y,w);
		}
		ans=-inf;k=0;
		dfs(1,0);
		printf("%d %d\n",ans,k);
	}
	return 0;
}


你可能感兴趣的:(编程,算法,百度,ACM,树形DP)