BZOJ3391: [Usaco2004 Dec]Tree Cutting网络破坏

【传送门:BZOJ3391


简要题意:

  给出一棵n个点的树,求出所有满足这个点的与这个点相连的边被删除后,形成的多棵子树的节点数都不超过n的一半的点

  如果没有,则输出NONE


题解:

  直接DFS求出每个点的子树的节点数和每个点的所有儿子的子树中的最大节点数

  一开始没看见是树的结构,想了半天,结果发现是水题


参考代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
    int x,y,next;
}a[21000];int len,last[11000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int ms[11000],tot[11000];
void dfs(int x,int fa)
{
    tot[x]=1;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(y!=fa)
        {
            dfs(y,x);
            tot[x]+=tot[y];
            ms[x]=max(ms[x],tot[y]);
        }
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        ins(x,y);ins(y,x);
    }
    memset(ms,0,sizeof(ms));
    dfs(1,0);
    bool bk=false;
    for(int i=1;i<=n;i++)
    {
        if(max(n-tot[i],ms[i])<=n/2)
        {
            printf("%d\n",i);
            bk=true;
        }
    }
    if(bk==false) printf("NONE\n");
    return 0;
}
posted @ 2018-04-28 15:19  Star_Feel  阅读(202)  评论(0编辑  收藏  举报