Description 给出一个树形图("tree-shaped" network),有N(1 <= N <= 10,000)个顶点。如果删除树上某一个顶点,整棵树就会分割成若干个部分。显然,每个部分内部仍保持连通性。 现在问:删除哪个点,使得分割开的每个连通子图中点的数量不超过N/2。如果有很多这样的点,就按升序输出。 例如,如图所示的树形图,砍掉顶点3或者顶点8,分割开的各部件。 Input 第1行:1个整数N,表示顶点数。顶点编号1~N 第2..N行:每行2个整数X和Y,表示顶点X与Y之间有一条边 Output 若干行,每行1个整数,表示一个符合条件的顶点的编号。如果没有顶点符合条件,则仅在第1行上输出"NONE" Sample Input 10 1 2 2 3 3 4 4 5 6 7 7 8 8 9 9 10 3 8 Sample Output 3 8 Data Constraint 题解 递归一次查找每一个点的子节点为根节点的子树中分别有多少个顶点,然后判断最多的有没有超过n/2,输出即可。 代码 type arr=record x,y,next:longint; end; var n:longint; a:array [0..40001] of arr; v:array [0..10001] of boolean; ls,d,f:array [0..10001] of longint; procedure dfs(x:longint); var i:longint; begin v[x]:=true; if (d[x]=1)and(x<>1) then begin f[x]:=1; exit; end; i:=ls[x]; while i<>0 do begin if v[a[i].y]=false then begin dfs(a[i].y); f[x]:=f[x]+f[a[i].y]; end; i:=a[i].next; end; inc(f[x]); end; var i,j,k,x,y:longint; temp:boolean; begin readln(n); for i:=1 to n-1 do begin readln(x,y); a[i].x:=x; a[i].y:=y; a[i].next:=ls[a[i].x]; ls[a[i].x]:=i; a[i+n-1].x:=y; a[i+n-1].y:=x; a[i+n-1].next:=ls[a[i+n-1].x]; ls[a[i+n-1].x]:=i+n-1; inc(d[x]);inc(d[y]); end; dfs(1); k:=n div 2; for i:=1 to n do begin temp:=true; j:=ls[i]; while j<>0 do begin if (f[a[j].y]<f[i])and(f[a[j].y]>k) then temp:=false; j:=a[j].next; end; if temp and (n-f[i]<=k) then writeln(i); end; end.