首页 > 其他分享 >树形DP——小红树

树形DP——小红树

时间:2023-04-02 18:22:06浏览次数:33  
标签:联通 idx int 树形 红树 权值 type 节点 DP

题目描述

小红拿到了一棵树,每个节点被染成了红色或者蓝色。 小红定义每条边的权值为:删除这条边时,形成的两个子树的同色连通块数量之差的绝对值。小红想知道,所有边的权值之和是多少?

输入描述

第一行输入一个正整数n,代表节点的数量。第二行输入一个长度为n且仅由'R'和'B'两种字符组成的字符串。第i个字符为'R'代表号节点被染成红色,为‘B"则被染成蓝色。接下来的n-1行,每行输入两个正整数u和v,代表节点u和节点v有一条边相连。1 <= n <=200000

 

 

 输出描述

一个正整数,代表所有边的权值之和。

 

题解

本题是典型的树形DP的问题

定义数组f,f[i]表示以i为根节点的子树中有多少个同色的连通块。

 

 我们可以将每个点的f值的初始值都设为1,然后递归地求每个点的f值。

如果节点x和 y的颜色不同,那么它们的同色联通块是独立的,直接累加即可:f[x] += f[y]。 如果节点 x 和 y的颜色相同,那么它们的同色联通块需要减去一个(因为它们本身算两个联通块,但是它们连接成了一个联通块),然后再累加:f[x] += f[y] - 1。 然后,我们需要对每条边计算权值。设 x - y是一条边,则有: 如果节点 x和 y的颜色相同,那么它们原本是连通的,但是现在因为断边变成了两个联通块,所以贡献为abs(f[1] - f[y] + 1 - f[y]); 如果节点 x和 y的颜色不同,那么它们原本是不连通的,现在因为连边变成了一个联通块,所以贡献为 abs(f[1] - f[y] - f[y]) 最后,我们将所有边的权值累加即可。 我们直接定义1为树的根节点,这就要dfs和计算的时候都从1开始。  

完整代码

#include <bits/stdc++.h>
using namespace std;

const int N = 200010;
int h[N], e[N], ne[N], idx;
int f[N];
char type[N];
int res = 0;
int n;

void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void dfs(int x, int fa) {
    for(int i = h[x]; i != -1; i = ne[i]) {
        int y = e[i];
        if(y == fa) continue;
        dfs(y, x);
        if(type[x] == type[y]) {
            f[x] += f[y] - 1;
        } else {
            f[x] += f[y];
        }
    }
}

void calc(int x, int fa) {
    for(int i = h[x]; i != -1; i= ne[i]) {
        int y = e[i];
        if(y == fa) continue;
        calc(y, x);
        if(type[x] == type[y]) {
            res += abs(f[1] + 1 - f[y] - f[y]);
        } else {
            res += abs(f[1] - f[y] - f[y]);
        }
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    memset(h, -1, sizeof h);
    for(int i = 1; i <= n; i++) {
        cin >> type[i];
    }
    for(int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        add(a, b);
        add(b, a);
    }
    for(int i = 1; i <= n; i++) f[i] = 1;
    dfs(1, -1);
    calc(1, -1);
    cout << res << '\n';
    return 0;
}

 

 

标签:联通,idx,int,树形,红树,权值,type,节点,DP
From: https://www.cnblogs.com/i-rong/p/17280949.html

相关文章

  • Leetcode(剑指offer专项训练)——DP专项(6)
    排序的数目题目给定一个由不同 正整数组成的数组nums,和一个目标整数target。请从nums中找出并返回总和为target的元素组合的个数。数组中的数字可以在一次排列中出现任意次,但是顺序不同的序列被视作不同的组合。题目数据保证答案符合32位整数范围。链接无效DFS......
  • Leetcode(剑指offer专项训练)——DP专项(5)
    最少的硬币数目给定不同面额的硬币coins和一个总金额amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。你可以认为每种硬币的数量是无限的。链接完全背包问题思路:主要是要自己推出动态转移方程\[F(i)=mi......
  • 【DP】LeetCode 64. 最小路径和
    题目链接64.最小路径和思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律表示状态假设到了右下角,考虑一下我们要存储的信息走到最后坐标的最小步数当前坐标的信息,用来判断是否走到了右下角很容易联想到使用......
  • 【DP】LeetCode 70. 爬楼梯
    题目链接70.爬楼梯思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律表示状态假设走到了最后一层台阶,考虑一下我们要存储的信息:走到这最后一层台阶的方法数当前台阶数,用于判断是否走到了最后一层台阶这时候......
  • Leetcode(剑指offer专项训练)——DP专项(4)
    加减的目标值给定一个正整数数组nums和一个整数target。向数组中的每个整数前添加 '+'或'-',然后串联起所有整数,可以构造一个表达式:例如,nums=[2,1],可以在2之前添加'+',在1之前添加'-',然后串联起来得到表达式"+2-1"。返回可以通过上述方法构造的、运算......
  • 关于网络通信中TCP/UDP的端口范围-以及在Linux系统中的使用权限说明
    关于TCP/UDP的端口号的范围都是0~65535 根据IANA定义,可以参考如下链接:https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtmlIANA将这些端口分成了3类,LastUpdated2023-03-30Portnumbersareassignedinvariousways,based......
  • 调试freeradius时遇到的 线程池以及udp相关问题
    调试线程池过程中遇到了一个return和pthread_exit的问题;google一下发现右如下概念首先,return语句和pthread_exit()函数的含义不同,return的含义是返回,它不仅可以用于线程执行的函数,普通函数也可以使用;pthread_exit()函数的含义是线程退出,它专门用于结束某个线程的执行。在主......
  • 项目一众筹网05_02_[树形开发]菜单管理、API文档发布到web服务器、配置文件里面修改to
    系列文章目录文章目录系列文章目录08-页面显示树形结构-前端-使用真实数据09-准备zTree的API文档(因为现在没有图标)==API文档发布到web服务器上去==配置文件里面修改tomcat的默认端口号(只需改动3个地方)10-前端-显示图标-分析思路(-页面显示树形结构)11-前端-显示图标-代码实现(-页面......
  • 项目一众筹网05_01_[树形结构开发]菜单维护-树形结构基础知识、自关联、zTree的介绍和
    树形结构开发]菜单维护文章目录树形结构开发]菜单维护01-菜单维护-树形结构基础知识-上==在数据库中怎么去表示树形关系====其实这就是自关联====我们怎么识别根节点==02-菜单维护-树形结构基础知识-下03-页面显示树形结构-后端-逆向工程==开发的细节:如何避免空指针异常:初始化==04-......
  • 简单理解 DP 套 DP
    复制粘贴的:通过一个外层的DP来计算使得另一个DP方程最终结果为特定值的输入数。例如求有多少种输入使得一个背包DP恰好答案为\(K\)。外层DP的状态是所有子DP的状态的值。子DP状态数很少,通常经过滚动数组优化,比如\(3n\)变成\(2\times3\))通常我们有技巧地枚......