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 }

 

posted @ 2017-10-16 12:18  Leohh  阅读(209)  评论(0编辑  收藏  举报