BZOJ 3391 [Usaco2004 Dec]Tree Cutting网络破坏(树形DP)

【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3391

【题目大意】

  给定一棵树,求分支size均不大于一半点数的点

【题解】

  递归的同时计算各个分支size,如果出现大于一半点数的则给这个点打上标记
  最后输出没有标记的点即可。

【代码】

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int N=10010;
int size[N],mark[N],n;
vector<int> v[N];
void dfs(int x,int fx){
    size[x]=1,mark[x]=1;
    for(int i=0;i<v[x].size();i++){
        int y=v[x][i];
        if(y!=fx){
            dfs(y,x);
            if(size[y]*2>n)mark[x]=0;
            size[x]+=size[y];
        }
    }if((n-size[x])*2>n)mark[x]=0;
}
int main(){
    while(~scanf("%d",&n)){
        for(int i=1;i<n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
            v[y].push_back(x);
        }dfs(1,0);
        int flag=1;
        for(int i=1;i<=n;i++)if(mark[i]){printf("%d
",i);flag=0;}
        if(flag)puts("NONE");
    }return 0;
}
原文地址:https://www.cnblogs.com/forever97/p/bzoj3391.html