sgu 149解题记录

来源:互联网 发布:北京百知教育骗局 编辑:程序博客网 时间:2024/05/20 16:11

149. Computer Network


time limit per test: 0.25 sec.
memory limit per test: 4096 KB
input: standard input
output: standard output
A school bought the first computer some time ago. 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 for each computer number Si - maximum distance, 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.

Input
There is natural number N (N<=10000) in the first line of input, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.

Output
Write N lines in output file. i-th line must contain number Si for i-th computer (1<=i<=N).

Sample test(s)

Input
3 1 1 1 2
Output

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();}

0 0