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; }