题意简述
题目链接

给定一棵无根树,每个节点要么是黑点要么是白点,要求对于每个节点u,选出包含u的一个连通子图,使cnt1-cnt2最大化,其中cnt1为该连通子图内白点数,cnt2为连通子图内黑点数。

算法概述
记每个节点的权值w[u]为1或-1,1表示该点为白点,-1表示该点为黑点。

定义dp[u]表示在以u为根的子树中选一张包含u的连通子图的所有方案中cnt1-cnt2的最大值。

显然dp[u]=w[u]+∑max(dp[v],0),其中v为u的子节点。这个式子的含义就是dp[u]必然是由u点以及其儿子的最大值组成的,而其所有儿子中,若某儿子的dp值小于0,则将其加上必然会使答案变得更差,故可以不选这个儿子,所以每次加之前要拿dp[v]与0做个比较。我们记vis[u]表示在计算节点u的父亲的dp值时,节点u是否有被选,1表示被选,0表示未选。

定义f[u]表示在整棵树中选一张包含u的连通子图的所有方案中,cnt1-cnt2的最大值。

考虑f[u]的组成:一部分是以其为根的子树,即dp[u];另一部分即是在全局中将其子树挖掉后剩下的部分。这两部分互相独立,分别取最大值即可。

考虑第二部分的计算:记u的父节点为fa,若vis[u]=1,则说明其包含在dp[fa]中,故这一部分即为f[fa]-dp[u];若vis[u]=0,即其不包含在dp[fa]中,则这一部分为f[fa]。最后将这一部分的值与0取max即可。

所以整个算法只需要两遍dfs,第一遍自底向上计算出dp数组,第二遍以f[1](强制1为根节点)自上向下计算出f数组,即为答案。

时间复杂度O(n)。

参考代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=2e5+10;

struct Edge{
    int to,next;
}edge[N<<1];int idx;
int h[N];

void add_edge(int u,int v){edge[++idx]={v,h[u]};h[u]=idx;}

int dp[N],f[N],vis[N],w[N];
int n;

void dfs1(int p,int fa)
{
    dp[p]=w[p];
    for(int i=h[p];~i;i=edge[i].next)
    {
        int to=edge[i].to;
        if(to==fa)continue;
        dfs1(to,p);
        if(dp[to]>0)
        {
            vis[to]=1;
            dp[p]+=dp[to];
        }
    }
}

void dfs2(int p,int fa)
{
    for(int i=h[p];~i;i=edge[i].next)
    {
        int to=edge[i].to;
        if(to==fa)continue;
        int val=f[p]-(vis[to]?dp[to]:0);
        f[to]=dp[to]+(val>0?val:0);
        dfs2(to,p);
    }
}

int main()
{
    memset(h,-1,sizeof h);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;scanf("%d",&x);
        w[i]=(x?x:-1);
    }
    for(int i=1;i<=n-1;i++)
    {
        int u,v;scanf("%d%d",&u,&v);
        add_edge(u,v);
        add_edge(v,u); 
    }
    
    dfs1(1,0);
    f[1]=dp[1];
    dfs2(1,0);
    
    for(int i=1;i<=n;i++)printf("%d ",f[i]);
    return 0;
}

CF1324F Maximum White Subtree相关推荐

  1. F:Maximum White Subtree(树形dp)

    Maximum White Subtree 思路 如果考虑其覆盖范围只会到其子树上,不会到其父节点上的话(假设的情况),这道题就非常好写了,就是一个简单的自底向上传递的树形dpdpdp.所以我们还要考 ...

  2. CodeForces - 1324F Maximum White Subtree(树形dp)

    题目链接:点击查看 题目大意:给出 n 个点组成的树,每个点都有一个颜色,非黑即白,现在问对于每个点而言,选出一个连通块,使得白色点的个数与黑色点的个数做差最大 题目分析:记录一下div3的第一次ak ...

  3. CF 1324-F Maximum White Subtree //树形换根dp

    题目链接 http://codeforces.com/problemset/problem/1324/F 题意 给你一棵树( n n n 个顶点)和一个数组 a i a_i ai​,每个顶点要不是白色 ...

  4. 【论文翻译】聚类算法研究

    论文题目:聚类算法研究 论文来源:聚类算法研究 翻译人:BDML@CQUT实验室 聚类算法研究 孙吉贵 , 刘 杰 , 赵连宇 Clustering Algorithms Research SUN J ...

  5. LeetCode笔记:Biweekly Contest 78

    LeetCode笔记:Biweekly Contest 78 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. 代码实现 ...

  6. iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务等等

    --系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用 ...

  7. 树形dp ---- 树形换根dp F - The Maximum Subtree

    题目链接 题目大意: 给定一颗树,求这个树的最大子树,且这个子树是一个good-tree. good-tree的定义是:每个节点可以表示成一个数值区间,而树上的边表示两个点表示的数值区间相交 解题思路 ...

  8. 【leetcode】654. Maximum Binary Tree

    题目如下: Given an integer array with no duplicates. A maximum tree building on this array is defined as ...

  9. hdu-5583 Kingdom of Black and White(数学,贪心,暴力)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5583 Kingdom of Black and White Time Limit: 2000/1000 ...

最新文章

  1. AAAI22奖项公布,9000投稿选出唯一杰出论文,中科院自动化所获Distinguished论文奖...
  2. [分享]关于windows下的小技巧
  3. P3373 【模板】线段树 2 (未完待续)
  4. python的一些 简单算法
  5. collections之defaultdict
  6. Python如何在控制台显示进度条
  7. 十二、深入JavaScript中的Date
  8. 一键拼出你的微信好友图片墙!
  9. 会议交流 | “数据智能与知识服务”研讨会的专家报告题目已更新!
  10. 外呼机器人起名_智能外呼机器人十大厂商
  11. pubmed 影响因子_如何在Pubmed利用影响因子筛选文献?
  12. OpenCV2:幼儿园篇 第八章 视频操作
  13. 【语音识别】基于matlab动态时间规整(DTW)孤立字语音识别【含Matlab源码 573期】
  14. js脚本实现自由复制百度文库文字
  15. Jenkins的安装及使用
  16. 天耀18期 - 11.封装类及常用类【作业】
  17. Java的时间格式化
  18. 修改自带input样式input:-internal-autofill-selected为透明色
  19. 双评价技术指南2020_双评价技术学习笔记(旧)
  20. 狼人杀总结之“警下预言家 必是真预言家”

热门文章

  1. python设置画布大小_python-Tkinter画布自动调整大小
  2. 锂离子电池HPPC测量
  3. 18650圆柱锂电池comsol5.6模型 参数已配置,电化学生热研究,三种放电倍率
  4. 会计记账公式、六要素、记账流程
  5. 开机后我的计算机打不开,电脑开机后图标打不开怎么办
  6. HTML5+CSS期末大作业:运动体育网站设计主题——体育铅球(5页)带注册 期末作业HTML代码
  7. 微信小程序支付(1)Uni-app平台API接口
  8. print中的逗号“,”打印出来相当于空格
  9. 进程管理API之find_get_pid
  10. 微信公众平台针对欺诈等违规行为处理结果公示