题意:给定一棵树,问删除哪个点,使余下的各个子树结点个数的最大值最小.
分析:先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.