计算机网络
Description
树的中心的定义:树的中心点是离它最远的结点的距离最近。具体地说,若某结点i是树的中心,那么i到树的最远的点的距离是最短的。比如说下面这棵边权为1的树中:
1----2----5----6
| |
3 4◆距离结点 1 最远的点是 6,距离为 3;
◆距离结点 2 最远的点是 6 或 3,距离为 2;
◆距离结点 3最远的点是6,距离为 4;
◆距离结点 4 最远的点是3或6,距离为 3;
◆距离结点 5 最远的点是3,距离为 3;
◆距离结点 6 最远的点是3,距离为 4;
由上面可以看出,每个结点都有一个距离最远的点的距离,其中距离2是最短的距离是2,所以点 2 就是树的中心。
用数学语言描述树的中心如下:
●设d(a,b)=树中两点之间的距离;
●设maxd(i)=MAX{d(i,j) | 1<=j<=N }
●那么树的中心结点为:MIN{maxd(i) | 1<=i<=N }
一棵树有一个中心或两个,若有两个中心,则他们必定是相邻的。比如下面这棵树,其中心有1和2两个。
1-----2----5
| |
3 4
现在你的任务是,给出一棵树,请找该树的中心,若有两个,请由小到大输出。
Input
第一行一个整数N,表示树的结点个数。
第二行有N-1个数字,第i个数字与编号为i+1的结点有边相连。
Output
输出仅一行按升序输出中心计算机的编号
这题是很显然的树形DP……
首先定义两个数组d1,d2(也可用一个数组d[][2]代替)
d1[x]表示到x的最大路径,d2[x]表示到x的次长路径。
然后两次dfs就可以做出来了。主要是懒得再写了题解了
下面上丑代码
#include<bits/stdc++.h>
using namespace std;
int h[100005],k[100005],y;
int d1[100005],d2[100005];
int n,x,i,j,cnt,rd[100005];
struct node {
int to,nx;
} e[200005];
void add(int x,int y) {
e[++cnt].to=y;
e[cnt].nx=h[x]