题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3534
题目大意:给出一颗n个节点的树,每条边对应一个长度,求出距离最大的两个节点之间长度,并找出一共有多少个顶点对。
实现代码如下:
/*求最长边的时候可以统计一下最长边的个数,
那么以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;
}