1. 程式人生 > >BZOJ 3391 [Usaco2004 Dec]Tree Cutting網絡破壞:dfs【無根樹 節點分枝子樹大小】

BZOJ 3391 [Usaco2004 Dec]Tree Cutting網絡破壞:dfs【無根樹 節點分枝子樹大小】

push pac namespace pre efi else line geo void

題目鏈接: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 }

BZOJ 3391 [Usaco2004 Dec]Tree Cutting網絡破壞:dfs【無根樹 節點分枝子樹大小】