比较简单的树形dp;
定义s[i]为节点i的子树节点数和(包括自身);叶子节点s[j]=1;
s[i]=signma(s[k])+1 (k是i的孩子)
则i满足的条件是 1.s[k]<=n div 2 (k为所有孩子节点)
2.n-s[k]<=n div 2;
由于n比较大,可以考虑用前向星来存储,这题想明白了还是很简单的,最后注意满足条件的节点升序输出;
1 type link=^node; 2 node=record 3 data:integer; 4 next:link; 5 end; 6 var c:array[0..10010] of link; 7 f,a:array[0..10010] of boolean; 8 s:array[0..10010] of longint; 9 i,n,x,y:integer; 10 w:boolean; 11 r:link; 12 procedure add(x,y:integer); //前向星 13 var p:link; 14 begin 15 new(p); 16 p^.data:=y; 17 p^.next:=c[x]; 18 c[x]:=p; 19 end; 20 procedure treedp(x:integer); 21 var ch:boolean; 22 i:integer; 23 r:link; 24 begin 25 ch:=true; 26 s[x]:=1; 27 f[x]:=true; 28 r:=c[x]; 29 while r<>nil do 30 begin 31 if not f[r^.data] then 32 begin 33 f[r^.data]:=true; //前向星是图结构,这里的标记是建立从父节点到子节点的关系 34 treedp(r^.data); 35 if s[r^.data]>n div 2 then ch:=false; 36 inc(s[x],s[r^.data]); 37 end; 38 r:=r^.next; 39 end; 40 if (n-s[x])>n div 2 then ch:=false; 41 if ch then a[x]:=true; 42 end; 43 begin 44 readln(n); 45 for i:=1 to n-1 do 46 begin 47 readln(x,y); 48 add(x,y); 49 add(y,x); 50 end; 51 fillchar(f,sizeof(f),false); 52 fillchar(a,sizeof(a),false); 53 treedp(1); //生成树任意一个节点都可以作为根节点 54 w:=false; 55 for i:=1 to n do 56 begin 57 if a[i] then 58 begin 59 w:=true; 60 writeln(i); 61 end; 62 end; 63 if not w then writeln('NONE'); 64 end.