Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7193 Accepted Submission(s): 3566

Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
5 1 1 2 1 3 1 1 1
3 2 3 4 4
题目大意:
给你N个点的一棵树,问距离每一个点最远的点的距离。
思路:
类似:http://blog.youkuaiyun.com/mengxiang000000/article/details/75578275
①我们设定Dp【u】表示以u为根的子树中,距离点u最远距离长度。
那么有:Dp【u】=max(Dp【v】+W(u,v));
②现在对于一个点u来讲,有两个方向,一个是子树方向,一个是非子树方向。
我们搞定了子树方向,就剩下非子树方向了。
那么设定F【u】表示非子树方向到点u节点最远的长度。
对于一个点来说,如果是非子树方向就有两种递推状态的方案:
1.从父亲节点来(从根节点到当前节点这条路径的长度):F【u】=F【from】+W(from,u);
2.从当前节点的兄弟节点而来;F【u】=max(Dp【brother】+W(from,u)+W(from,v));
如果存在一个点有多个儿子的情况,从2状态转移的时间复杂度会达到O(n^2),很危险,所以我们再维护一个数组Id【u】表示以u为根的子节点中Dp【v】值最大的节点编号。同时维护从这个点u到这个最大值点v直接路径的长度(W(u,v));
过程维护一下即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
struct node
{
int from;
int to;
int w;
int next;
}e[35000];
int head[15000];
int fa[15000];
int maxn[15000];
int Id[15000];
int F[15000];
int dp[15000];
int n,cont;
void add(int from,int to,int w)
{
e[cont].to=to;
e[cont].w=w;
e[cont].next=head[from];
head[from]=cont++;
}
void dfs(int u,int from)
{
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
int w=e[i].w;
if(v==from)continue;
else
{
dfs(v,u);
if(dp[v]+w>dp[u])
{
dp[u]=dp[v]+w;
Id[u]=v;
}
}
}
}
void Dfs(int u,int from,int prew)
{
fa[u]=from;
if(from!=-1)F[u]=max(F[from]+prew,F[u]);
if(from!=-1)
{
if(u==Id[from])
{
for(int i=head[from];i!=-1;i=e[i].next)
{
int v=e[i].to;
int w=e[i].w;
if(v==u)continue;
if(from!=-1&&v==fa[from])continue;
if(v==from)continue;
F[u]=max(dp[v]+prew+w,F[u]);
}
}
else
{
F[u]=max(F[u],dp[from]+prew);
}
}
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
int w=e[i].w;
if(v==from)continue;
Dfs(v,u,w);
}
}
int main()
{
while(~scanf("%d",&n))
{
cont=0;
memset(head,-1,sizeof(head));
memset(F,0,sizeof(F));
memset(dp,0,sizeof(dp));
for(int i=2;i<=n;i++)
{
int faa,w;
scanf("%d%d",&faa,&w);
add(i,faa,w);
add(faa,i,w);
}
dfs(1,-1);
Dfs(1,-1,0);
/*
for(int i=1;i<=n;i++)
{
printf("%d ",dp[i]);
}
printf("\n");
for(int i=1;i<=n;i++)
{
printf("%d ",F[i]);
}
printf("\n");*/
for(int i=1;i<=n;i++)
{
printf("%d\n",max(F[i],dp[i]));
}
}
}