您的位置:首页 > 其它

HDU2196computer(树上最远距离 + DP)

2016-02-15 12:39 239 查看

Computer

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4990 Accepted Submission(s): 2509


[align=left]Problem Description[/align]
A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int Max = 10000 + 10;
struct Node
{
int to,next,len;
};
Node edge[2 * Max];
int head[Max], tol;
int maxn[Max],maxnId[Max]; //最远距离和最远距离对应的序号
int smaxn[Max],smaxnId[Max]; //次远距离和次远距离对应的序号
void add_edge(int a, int b, int len)
{
edge[tol].to = b;
edge[tol].next = head[a];
edge[tol].len = len;
head[a] = tol++;
}
void dfs1(int u, int p)
{
maxn[u] = smaxn[u] = 0;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(v == p)  //如果是父节点跳过
continue;
dfs1(v, u);
if(smaxn[u] < maxn[v] + edge[i].len)  //如果子节点的最远距离大于次远距离,就更新次远距离;先更新次远距离,由次远距离和最远距离比较更新最远距离
{
smaxn[u] = maxn[v] + edge[i].len;
smaxnId[u] = v;
if(smaxn[u] > maxn[u])
{
swap(smaxn[u], maxn[u]);
swap(smaxnId[u], maxnId[u]);
}
}
}
}
void dfs2(int u, int p)
{
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(v == p)
continue;
if(v == maxnId[u])  //如果父节点方向最远距离经过这个子节点
{
if(smaxn[u] + edge[i].len > smaxn[v]) //选择次远距离,因为最远距离经过v点
{
smaxn[v] = smaxn[u] + edge[i].len;
smaxnId[v] = u;
if(maxn[v] < smaxn[v])
{
swap(maxn[v], smaxn[v]);
swap(maxnId[v], smaxnId[v]);
}
}
}
else
{
if(maxn[u] + edge[i].len > smaxn[v])
{
smaxn[v] = maxn[u] + edge[i].len;
smaxnId[v] = u;
if(maxn[v] < smaxn[v])
{
swap(maxn[v], smaxn[v]);
swap(maxnId[v], smaxnId[v]);
}
}
}
dfs2(v, u);
}
}
int main()
{
int n,v,len;
while(scanf("%d", &n) != EOF)
{
tol = 0;
memset(head, -1, sizeof(head));
for(int i = 2; i <= n; i++)
{
scanf("%d%d", &v, &len);
add_edge(i, v, len);
add_edge(v, i, len);
}
dfs1(1, -1); //向下
dfs2(1, -1);
for(int i = 1; i <= n; i++)
printf("%d\n", maxn[i]);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: