Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3849 | Accepted: 2304 |
Description
Input
Output
Sample Input
10 1 2 2 3 3 4 4 5 6 7 7 8 8 9 9 10 3 8
Sample Output
3 8
Hint
Source
POJ 2378:
题目意思:
在一棵树上去掉一些点,使得这棵树可以变成一些包含的顶点数目不超过原来的树的一般的一些树,求需要删除的节点,如果有多个节点,按照升序输出;
解题思路:
对树进行宽度优先遍历,如果一个结点的所有以这个节点的子节点为根的树的节点数不超过n/2,并且n减去以这个节点为根节点的树的节点个数小于等于n/2,则这个节点为可以删除的节点;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<vector> 7 using namespace std; 8 const int maxn=10007; 9 int dp[maxn]; 10 bool input[maxn]; 11 vector<int> G[maxn]; 12 int n; 13 void init() 14 { 15 memset(dp,0,sizeof(dp)); 16 memset(input,0,sizeof(input)); 17 for(int i=0;i<maxn;i++) 18 G[i].clear(); 19 } 20 void bfs(int point,int father) 21 { 22 dp[point]=1; 23 bool flag=true;int num=0; 24 for(int i=0;i<G[point].size();i++) 25 { 26 int v=G[point][i]; 27 if(v==father) continue; 28 bfs(v,point); 29 if(dp[v]>n/2) flag=false; 30 dp[point]+=dp[v]; 31 } 32 if(flag&&n-dp[point]<=n/2)input[point]=true; 33 } 34 int main() 35 { 36 //freopen("in.txt","r",stdin); 37 int a,b,root; 38 while(~scanf("%d",&n)){ 39 init();root=-1; 40 for(int i=1;i<n;i++) 41 { 42 scanf("%d %d",&a,&b); 43 G[a].push_back(b); 44 G[b].push_back(a); 45 } 46 bfs(1,-1); 47 for(int i=1;i<=n;i++) if(input[i]) printf("%d\n",i); 48 } 49 return 0; 50 }
原文:http://www.cnblogs.com/codeyuan/p/4312208.html