149. Computer Network
memory limit per test: 4096 KB
output: standard output
Input
Output
Sample test(s)
Input
3
题目大意:
一个学校在很久以前买了第一台电脑。在最近几年学校买了n-1台新的电脑。任意一台新的电脑都与一台早买的电脑有稳定联系。学校的管理员对网速很焦虑并且想知道对于任意一台电脑的最大距离,也就是离它最远电脑与他的距离。
解题记录:
好早之前做的,而且唯一有完整记录保存的题目,扒出来直接贴了。
解题报告:
由此给出的数据可分析,N-1条边,而且任意2点都是相连的,可得出为构成的是一棵树。需要做的事情是,给任意该树中的节点,求出该节点到树的任意节点中的最远长度。
数据结构:
树,然而我们在每个节点里面记录一些基本信息、拓展信息。
tree[i]基本信息:
1. 父节点(father);
2. 与父节点的长度(length);
3. 第一代叶节点(可用邻接表实现)(child,next)。
拓展信息:
1. 在以该节点为根的子树中距离最远的长度(max1);
2. 在以该节点为根的子树中距离次远的长度(max2);
3. 在以该节点为根的子树中距离最远的长度的第一代叶节点(where);
算法:
1. 进行一次树的遍历,将每个节点的拓展信息完善(计算出max1,max2,(要求max1,max2的第一代叶节点不一 致))。
2. 对每个节点i,答案为以下几个计算结果的最大值:
1. 以该节点i为子树,子树内部最远距离max1;
2. 以该节点i为子树,子树外部到该节点i的最远距离。
遍历所有直系祖辈节点temp1,同时用sum记录从节点i到temp1的距离。
1. 若以祖辈节点temp1为子树的最远距离的第一代叶节点不是i的直系父辈节点,到该祖辈节点的有效最远距离为tree[temp1].max1+sum;
2. 若以祖辈节点temp1为子树的最远距离的第一代叶节点是i的直系父辈节点,到该祖辈节点的有效最远距离为tree[temp1].max2+sum;
3. 若其子树的最远距离的第一代叶节点,为节点i的直系父辈节点,则实效距离为第一代 叶节点到祖辈节点temp1的length。所以此时应该选次远。
代码:
#include <cstdio>
struct list{
int father,length,child,next;
int max1,where,max2;
};
int n;
list tree[10001];
int max(int x,int y) {
if (x>y) return(x);
return(y);
}
void init() {
scanf("%d\n",&n);
for (int i=2;i<=n;i++) {
scanf("%d%d\n",&tree[i].father,&tree[i].length);
tree[i].next=tree[tree[i].father].child;
tree[tree[i].father].child=i;
}
}
void dfs(int num) {
int childnum=tree[num].child;
while (childnum!=0) {
dfs(childnum);
if (tree[childnum].max1+tree[childnum].length>tree[num].max1) {
tree[num].max2=tree[num].max1;
tree[num].max1=tree[childnum].max1+tree[childnum].length;
tree[num].where=childnum;
}
else if (tree[childnum].max1+tree[childnum].length>tree[num].max2)
tree[num].max2=tree[childnum].max1+tree[childnum].length;
childnum=tree[childnum].next;
}
}
void work() {
dfs(1);
for (int i=1;i<=n;i++) {
int temp1=i,sum=0,ans=tree[i].max1;
while (tree[temp1].father!=0) {
sum+=tree[temp1].length;
if (tree[tree[temp1].father].where!=temp1)
ans=max(ans,tree[tree[temp1].father].max1+sum);
else
ans=max(ans,tree[tree[temp1].father].max2+sum);
temp1=tree[temp1].father;
}
printf("%d\n",ans);
}
}
int main() {
init();
work();
}