题目大意
给定一个无向图形成一棵树,截去某个点后,森林中的树要是每棵树中的节点数都不超过原来总结点数的1/2,那么就把这个点输出
否则输出NONE
前面也做了思想一样的题目POJ 1655 Balancing Act && POJ 3107 Godfather
不理解可以看看
1 /* 2 sum[i]表示i对应子树中的节点总数 3 down[i]表示截去i后,i下方子树断开成森林中最大的那棵子树的节点数 4 i取走后,往上走的子树长度为 n -sum[i] 5 rec[i] = max(down[i] , n -sum[i]); 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <iostream> 10 using namespace std; 11 12 const int N = 10005; 13 int first[N] , k , down[N] , sum[N] , rec[N]; 14 15 struct Edge{ 16 int y , next; 17 }e[N<<1]; 18 19 void add_edge(int x , int y) 20 { 21 e[k].y = y , e[k].next = first[x]; 22 first[x] = k++; 23 } 24 25 void dfs1(int u , int fa) 26 { 27 sum[u] = 1; 28 for(int i = first[u] ; i!=-1 ; i=e[i].next) 29 { 30 int v = e[i].y; 31 if(v == fa) continue; 32 dfs1(v , u); 33 sum[u] += sum[v]; 34 } 35 } 36 37 void dfs2(int u , int fa) 38 { 39 for(int i = first[u] ; i!=-1 ; i=e[i].next) 40 { 41 int v = e[i].y; 42 if(v == fa) continue; 43 dfs2(v , u); 44 down[u] = max(sum[v] , down[u]); 45 } 46 } 47 48 int main() 49 { 50 // freopen("a.in" , "r" , stdin); 51 int n , x , y; 52 while(scanf("%d" , &n)==1){ 53 memset(first , -1 , sizeof(first)); 54 k=0; 55 for(int i=1 ; i<n ; i++){ 56 scanf("%d%d" , &x , &y); 57 add_edge(x , y); 58 add_edge(y , x); 59 } 60 61 memset(down , 0 , sizeof(down)); 62 dfs1(1 , -1); 63 dfs2(1 , -1); 64 int num=0; 65 for(int i=1 ; i<=n ; i++){ 66 rec[i] = max(down[i] , n-sum[i]); 67 if(rec[i]<=n/2){ 68 printf("%d " , i); 69 num++; 70 } 71 } 72 if(num == 0) puts("NONE"); 73 } 74 return 0; 75 }