【闲话】就算熬夜,也一定要先记录下这个题,我太开心了。。。。
【题意】给了一颗树,询问这个树里面每个点到树上其他点的最大距离,这个题是属于树形DP的,在前几周还讲到了这个题,(一切都是缘分),今天在整理树形dp又发现这个题,然后这里说了,这个题可以直接维护每个点到树直径端点的两个距离的最大值!
【分析】这么神奇吗?马上翻出树直径的板子,构思一下,20分钟写完debug的过程有点磁力呀,把max写成Min,看了好久,过掉样例,交上去TLE,原来是E【】写错了,应该是20004,写成2004,太不细心了。改掉过了这题了!
【开心】真的好开心,这个树形dp,竟然用看似很暴力的方法过掉了,以后可以吹一下这个题了!明早信号与系统,果断睡觉!!!
【AC代码】
//Tree_dp cpp //just_sort 2016/4/17 #include <queue> #include <stack> #include <assert.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const int maxn = 10002; const int maxm = 20004; struct Edge{ int v,w,next; }E[maxm]; int n,tot; int head[maxn],d1[maxn],d2[maxn];//d1保存点到树直径左端点的距离,d2保存点到树直径右端的距离 int x;//记录直径能到达的端点 void Init() { tot = 0; memset(head,-1,sizeof(head)); } void Add_Edge(int u,int v,int w) { E[tot].v=v,E[tot].w=w; E[tot].next = head[u]; head[u] = tot++; E[tot].v=u,E[tot].w=w; E[tot].next = head[v]; head[v] = tot++; } void work() { } void dfs(int u,int fa,int d[])//寻找直径,更新距离!!! { int i,v; for(i=head[u]; ~i; i=E[i].next) { v = E[i].v; if(v!=fa) { d[v] = d[u] + E[i].w; if(d[x]<d[v]) x=v; dfs(v,u,d); } } } int main() { int v,w; while(~scanf("%d",&n)) { Init(); for(int i=2; i<=n; i++) { scanf("%d%d",&v,&w); Add_Edge(i,v,w); } d1[1]=0,x=1,dfs(1,0,d1); d1[x]=0, dfs(x,0,d1); d2[x]=0, dfs(x,0,d2); for(int i=1; i<=n; i++) { printf("%d\n",max(d1[i],d2[i])); } } return 0; }