POJ-2378 Tree Cutting
题目大意:一棵n个节点的树,找出所有的点满足:删除它之后,产生的最大(这里节点数最多即为最大)新树中节点数不超n的一半。
题目分析:两次深搜,过程类似求重心。
代码如下:
# include<iostream> # include<cstdio> # include<cstring> # include<vector> # include<queue> # include<list> # include<set> # include<map> # include<string> # include<cmath> # include<cstdlib> # include<algorithm> using namespace std; # define LL long long const int N=1005; const int INF=1000000000; vector<int>e[N*10]; int size[N*10]; int n,dp[N*10]; void init() { for(int i=1;i<=n;++i) e[i].clear(); int a,b; for(int i=1;i<n;++i){ scanf("%d%d",&a,&b); e[a].push_back(b); e[b].push_back(a); } } void dfs(int u,int fa) { size[u]=1; for(int i=0;i<e[u].size();++i){ int v=e[u][i]; if(v==fa) continue; dfs(v,u); size[u]+=size[v]; } } void dfs1(int u,int fa) { dp[u]=n-size[u]; for(int i=0;i<e[u].size();++i){ int v=e[u][i]; if(v==fa) continue; dp[u]=max(dp[u],size[v]); dfs1(v,u); } } void solve() { dfs(1,-1); dfs1(1,-1); bool flag=true; for(int i=1;i<=n;++i){ if(dp[i]<=n/2){ printf("%d\n",i); flag=false; } } if(flag) printf("NONE\n"); } int main() { while(~scanf("%d",&n)) { init(); solve(); } return 0; }