zoukankan      html  css  js  c++  java
  • Codeforces 709E. Centroids 树形DP

    题目链接:http://codeforces.com/contest/709/problem/E

    题意:

      给你一棵树,你可以任删一条边和加一条边,只要使得其仍然是一棵树,输出每个点是否都能成为重心

    题解:

      做题多动手,画一画;

      假设要求当前节点i是否能经过操作成为重心,将它提起来为根,那么可以知道,就是选其中一颗子树提到以根为父亲的情况使得删去根之后每个子树点数和最多不超过n/2

      回来看,这颗子树要么来自自身子树下,要么来自父亲节点,这个时候我们dfs出需要的东西,也就是能够提出来的子树点数和最大的且不超过n/2的那颗是多少,再进行判断

      我的做法:找到每个节点以下的节点数目和能提出来的最多的数目 以及 最多 和 次多转移来的节点

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 5e5+10, maxn = 1e3+20, mod = 1e9+7, inf = 2e9;
    
    vector<int > G[N];
    int ans[N],submax[N],max1[N],max2[N],sz[N],n;
    void dfs(int u,int f) {
        sz[u] = 1;
        for(int i = 0; i < G[u].size(); ++i) {
            int to = G[u][i];
            if(to == f) continue;
            dfs(to,u);
            sz[u] += sz[to];
            if(submax[to] > submax[u]) {
                submax[u] = submax[to];
                max2[u] = max1[u];
                max1[u] = to;
            }
            else if(submax[max2[u]] < submax[to]) max2[u] = to;
        }
        if(sz[u] <= n/2) submax[u] = sz[u];
    }
    void dfs(int u,int f,int pre) {
        int flag = 1;
        for(int i = 0; i < G[u].size(); ++i) {
            int to = G[u][i];
            if(to == f) {
                int temp = n - sz[u];
                if(temp>n/2 && temp - pre > n/2) flag = 0;
            }
            else {
                if(sz[to] > n/2 && sz[to] - submax[to] > n/2) flag = 0;
            }
        }
        ans[u] = flag;
        for(int i = 0 ; i < G[u].size(); ++i) {
            int to = G[u][i];
            if(to == f) continue;
            int temp;
            if(n - sz[to] <= n/2) temp = n - sz[to];
            else {
                if(to == max1[u]) temp = max(pre,submax[max2[u]]);
                else temp = max(pre,submax[max1[u]]);
            }
            dfs(to,u,temp);
        }
    }
    int main() {
        int u,v;
        scanf("%d",&n);
        for(int i = 1; i < n; ++i) {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1,0);
        dfs(1,0,0);
        for(int i = 1; i <= n; ++i) cout<<ans[i]<<" ";
        return 0;
    }
  • 相关阅读:
    我的WCF之旅(1):创建一个简单的WCF程序
    网页设计中颜色的搭配
    CSS HACK:全面兼容IE6/IE7/IE8/FF的CSS HACK
    UVa 1326 Jurassic Remains
    UVa 10340 All in All
    UVa 673 Parentheses Balance
    UVa 442 Matrix Chain Multiplication
    UVa 10970 Big Chocolate
    UVa 679 Dropping Balls
    UVa 133 The Dole Queue
  • 原文地址:https://www.cnblogs.com/zxhl/p/6574809.html
Copyright © 2011-2022 走看看