/*先走一遍dfs找到每个点到他的子节点的位置,回溯的时候找到最大值和次大值 再用一个dfs来更新值,先看是否是u最长路上的点,如果是的话用最大值+权值更新最大值和次大值,否则的话用次大值+权值更新最大值和次大值 */ #include<stdio.h> #include<string.h> #define N 11000 struct node { int u,v,w,next; } bian[N*2]; int ma[N*2],ma2[N*2]; int n,yong,visit[N],head[N]; void addedge(int u,int v,int w) { bian[yong].u=u; bian[yong].v=v; bian[yong].w=w; bian[yong].next=head[u]; head[u]=yong++; } int dfs(int u) { visit[u]=1; int max1=0,max2=0,i,f; for(i=head[u]; i!=-1; i=bian[i].next) { int v=bian[i].v; if(!visit[v]) { f=dfs(v)+bian[i].w; if(max1<f) { max2=max1; max1=f; } else if(max2<f) max2=f; } } ma[u]=max1;//找到最大值和次大值 ma2[u]=max2; return max1; } int MAX(int a,int b) { return a>b?a:b; } void dfs1(int u) { int i; visit[u]=1; for(i=head[u]; i!=-1; i=bian[i].next) { int v=bian[i].v; if(visit[v])continue; if(bian[i].w+ma[v]!=ma[u])//如果没有在最长边上 { if(ma[v]<ma[u]+bian[i].w)//和v到子节点比较更新最大值 { ma2[v]=ma[v]; ma[v]=ma[u]+bian[i].w; } else if(ma2[v]<ma[u]+bian[i].w)//刚开始没有考虑还需要实时更新次大值 ma2[v]=ma[u]+bian[i].w; } else { if(ma[v]<ma2[u]+bian[i].w)//在最长边上 { ma2[v]=ma[v]; ma[v]=ma2[u]+bian[i].w; } else if(ma2[v]<ma2[u]+bian[i].w) ma2[v]=ma2[u]+bian[i].w; } dfs1(v); } return ; } int main() { int i,a,b; while(scanf("%d",&n)!=EOF) { yong=0; memset(head,-1,sizeof(head)); for(i=2; i<=n; i++) { scanf("%d%d",&a,&b); addedge(i,a,b); addedge(a,i,b); } memset(ma,0,sizeof(ma)); memset(ma2,0,sizeof(ma2)); memset(visit,0,sizeof(visit)); dfs(1); memset(visit,0,sizeof(visit)); dfs1(1); for(i=1; i<=n; i++) printf("%d\n",ma[i]); } return 0; }
hdu 2196 树形dp
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
HDU 2196 Computer (树形DP)
两次DFS,先从下往上搜一次,记录每个点到子树的最长距离与次长距
ACM c语言 算法 编程 树形DP -
hdu 2196(经典树形dp)
题意:给你一颗边带权值的树,求树上的每一点中去更新它。记录最大和次大主要还是为了更新父亲节点的状态,因为父亲节
dp 子节点 #include i++ -
【hdu 2196 Computer 】(树形dp求最长路)
:给一棵树,求树上任意顶点到其他各点的最大值。 分析: 可以容易知道 用树形dp求最长路 首先一次dfs 记录任意顶点到其他各点的最长距离
算法与数据结构 模板 POJ ACM_模板题 树状DP poj -
HDU 2196 Computer (树形DP)
题意:给一棵树,问每个点到其他点的最远距离是多少?思路
树形DP i++ #define 深搜 javascript