题目描述
有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1。现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那么村长应该要把会议地点设置在哪个村民的家中,并且这个距离总和最小是多少?若有多个节点都满足条件,则选择节点编号最小的那个点。
输入输出格式
输入格式:
第一行。一个数n,表示有n个村民。
接下来n-1行,每行两个数字a和b,表示村民a的家和村民b的家之间存在一条路径。
输出格式:
一行输出两个数字x和y
x表示村长将会在哪个村民家中举办会议
y表示距离之和的最小值
输入输出样例
输入样例#1:
4
1 2
2 3
3 4
输出样例#1:
2 4
说明
【数据范围】
70%数据n<=1000
100%数据n<=50000
program df;
type point=^node;
node=record
date,ends:longint;
next:point;
end;
var i,j,n,m,x,y,z,k,t,root,size:longint;
path:array[0..100000] of point;
d:array[0..100000] of longint;
b:array[0..100000] of boolean;
function max(x,y:longint):longint;
begin
if x>y then exit(x)
else exit(y);
end;
procedure com(x,y:longint);
var i:point;
begin
i:=path[x];
new(path[x]);
path[x]^.ends:=y;
path[x]^.next:=i;
end;
procedure dfs(x:longint);
var i:point;
y,t:longint;
begin
d[x]:=0; t:=0;
b[x]:=true;
i:=path[x];
while i<>nil do
begin
y:=i^.ends;
if not b[y] then
begin
dfs(y);
d[x]:=d[x]+d[y]+1; //记录该点的子节点个数
t:=max(t,d[y]+1);
end;
i:=i^.next;
end;
t:=max(t,n-d[x]-1); //记录以该点为树根的子树中含有子节点最多的子树的节点数
if (size>t) or ((size=t) and (root>x)) then //以子节点多为保证,取编号最小(可理解为找一个可以近似把树分成两半的点为树根)
begin
size:=t;
root:=x; //记录树根
end;
end;
begin
readln(n);
for i:=1 to n-1 do
begin
readln(x,y);
com(x,y);
com(y,x);
end;
size:=10000000;
dfs(1);
fillchar(b,sizeof(b),false);
z:=0;
dfs(root);
for i:=1 to n do
z:=z+d[i];
writeln(root,’ ‘,z);
end.