BZOJ 3391 [Usaco2004 Dec]Tree Cutting网络破坏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3391 [Usaco2004 Dec]Tree Cutting网络破坏相关的知识,希望对你有一定的参考价值。

实现不难,对我这种辣鸡来说有一定的思维量。

对于每个点我们只需要知道它的子树大小的总和和它最大的子树大小是多少就可以了。

因为对于每个点 只要知道了它的子树大小的总和那么也就知道了 它的所有父亲以及兄弟的数量(n-子树大小)

因为对于这个点来说,割去后对答案产生影响的只有它最大的子树大小。

 

如果割去这个点后 它的所有父亲以及兄弟的数量<=n/2 同时 最大的子树大小也<=n/2

那么一定是可行的。

#include <cstdio>
#include <algorithm>

using std::max;

struct node{
    int u,v,next;
    node(){}
    node(int _u,int _v,int _next){
        u = _u;
        v = _v;
        next = _next;
    }
}Edge[20005];

int n,head[20005],Count;
int sum[20005],Max[20005];

inline void AddEdge(int u,int v){
    Count++;
    Edge[Count] = node(u,v,head[u]);
    head[u] = Count;
}

void dfs(int x,int fa){
    sum[x]=1;
    for(int i=head[x];i;i=Edge[i].next){
        int v = Edge[i].v;
        if(v==fa) continue;
        dfs(v,x);
        sum[x]+=sum[v];
    }    
    for(int i=head[x];i;i=Edge[i].next){
        int v = Edge[i].v;
        Max[x] = max(Max[x],sum[v]);
    }
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        AddEdge(u,v);
        AddEdge(v,u);
    }
    dfs(1,-1);
    int limit = n/2;
    for(int i=1;i<=n;i++){
        if(n-sum[i]<=limit && Max[i] <= limit ) printf("%d\n",i);
    }
    return 0;
}

 

以上是关于BZOJ 3391 [Usaco2004 Dec]Tree Cutting网络破坏的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3390 Usaco2004 Dec Bad Cowstractors 牛的报复

Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题

bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 -- 贪心

bzoj 3390: [Usaco2004 Dec]Bad Cowtractors牛的报复 -- 最大生成树

bzoj3389:[Usaco2004 Dec]Cleaning Shifts安排值班

[USACO 2004DEC] Navigation Nightmare