题意:给定一棵树,问删除哪个点,使余下的各个子树结点个数的最大值最小.
分析:先DFS一次,求出以每个节点为根的子树的节点个数s[i].
设f[i]表示去掉i后,余下的各个子树结点个数的最大值.
f[i]=max(n-s[i],max{s[j]}). (j为i的儿子).
这样再DFS一次,求出max{f[i]}即为答案.
code:
type edge=record
v,n:longint;
end;
const maxn=20001;
oo=100000000;
var e:array[0..maxn*2] of edge;
h,s,f:array[0..maxn] of longint;
vis:array[0..maxn] of boolean;
dnum,d,n,i,u,v,cnt,min,mi:longint;
procedure swap(var a,b:longint);
var tmp:longint;
begin
tmp:=a; a:=b; b:=tmp;
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a); exit(b);
end;
procedure add(u,v:longint);
begin
inc(cnt);
e[cnt].v:=v;
e[cnt].n:=h[u];
h[u]:=cnt;
end;
procedure dfs(u:longint);
var v,p:longint;
begin
vis[u]:=true;
p:=h[u];
while p<>0 do
begin
v:=e[p].v;
if not vis[v] then
begin
dfs(v);
inc(s[u],s[v]);
end;
p:=e[p].n;
end;
inc(s[u]);
end;
procedure dp(u:longint);
var v,p,tmp:longint;
begin
vis[u]:=true;
tmp:=n-s[u];
p:=h[u];
while p<>0 do
begin
v:=e[p].v;
if not vis[v] then
begin
dp(v);
tmp:=max(tmp,s[v]);
end;
p:=e[p].n;
end;
f[u]:=tmp;
end;
begin
readln(dnum);
for d:=1 to dnum do
begin
fillchar(h,sizeof(h),0);
fillchar(f,sizeof(f),0);
fillchar(s,sizeof(s),0);
cnt:=0;
readln(n);
for i:=1 to n-1 do
begin
readln(u,v);
add(u,v);
add(v,u);
end;
fillchar(vis,sizeof(vis),0);
dfs(1);
fillchar(vis,sizeof(vis),0);
dp(1);
min:=oo; mi:=0;
for i:=1 to n do
if f[i]<min then
begin
min:=f[i];
mi:=i;
end;
writeln(mi,' ',min);
end;
end.
浙公网安备 33010602011771号