BZOJ 3391 [Usaco2004 Dec]Tree Cutting网络破坏:dfs【无根树 节点分枝子树大小】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3391
题意:
给你一棵无根树,求分支size均不大于一半点数的点。
题解:
假定1为根。
dfs时统计siz[i]和par[i]。
对于每个节点判断一下子树大小siz[son]和自己往上的子树大小n - siz[now]。
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <vector> 5 #define MAX_N 10005 6 7 using namespace std; 8 9 int n; 10 int par[MAX_N]; 11 int siz[MAX_N]; 12 vector<int> ans; 13 vector<int> edge[MAX_N]; 14 15 void read() 16 { 17 cin>>n; 18 int a,b; 19 for(int i=0;i<n-1;i++) 20 { 21 cin>>a>>b; 22 edge[a].push_back(b); 23 edge[b].push_back(a); 24 } 25 } 26 27 void dfs(int now,int p) 28 { 29 par[now]=p; 30 siz[now]=1; 31 for(int i=0;i<edge[now].size();i++) 32 { 33 int temp=edge[now][i]; 34 if(temp!=p) 35 { 36 dfs(temp,now); 37 siz[now]+=siz[temp]; 38 } 39 } 40 } 41 42 void solve() 43 { 44 dfs(1,-1); 45 for(int i=1;i<=n;i++) 46 { 47 int flag=true; 48 for(int j=0;j<edge[i].size();j++) 49 { 50 int temp=edge[i][j]; 51 if(temp!=par[i] && siz[temp]*2>n) 52 { 53 flag=false; 54 break; 55 } 56 } 57 if((n-siz[i])*2>n) flag=false; 58 if(flag) ans.push_back(i); 59 } 60 } 61 62 void print() 63 { 64 if(!ans.size()) cout<<"NONE"<<endl; 65 else 66 { 67 for(int i=0;i<ans.size();i++) 68 { 69 cout<<ans[i]<<endl; 70 } 71 } 72 } 73 74 int main() 75 { 76 read(); 77 solve(); 78 print(); 79 }