Codeforces Round 928 G. Vlad and Trouble at MIT 【树形DP】

news2024/10/26 2:31:50

G. Vlad and Trouble at MIT

G

题意

给定一颗 n n n 个节点的树,每个节点有一个学生,学生有三种类型:

  1. 参加派对的 P P P 类型,会制造噪音
  2. 想要睡觉的 S S S 类型,不希望被吵到
  3. 有没有噪音都可以的 C C C 类型

噪音会沿着树上的边不停传播,除非在某些边建一堵,现在给定每个节点的学生类型 s i s_i si

求出最少建多少堵墙可以满足 S S S 类型学生不被打扰

思路

我们可以想象一下从 P P P 类型的学生节点会流出蓝色的水流,而 S S S 类型的学生节点会流出红色的水流,我们要求蓝色和红色的水流不能相交,通过建墙后,可能有些节点是没有水流的。那么我们可以发现每个节点只有三种状态:蓝色水流、红色水流、没有水流。

我们对于当前的节点 u u u 和它的子节点 v v v,可以发现如果 u u u 是蓝色的,那么 v v v 必须是蓝色或者没有水流,否则如果 v v v 是红色,就必须建一堵墙来隔离。如果 u u u 没有水流,那么 v v v 必须没有水流,或则建墙隔离。

这里我们就可以发现是存在子状态的,我们可以用 d p [ u ] [ 0 ] , d p [ u ] [ 1 ] , d p [ u ] [ 2 ] dp[u][0],dp[u][1],dp[u][2] dp[u][0],dp[u][1],dp[u][2] 分别表示节点 u u u 没有水流、蓝色、红色需要建的最少的墙的数量,那么最终的答案就是: m i n ( d p [ 1 ] [ 0 ] , d p [ 1 ] [ 1 ] , d p [ 1 ] [ 2 ] ) min(dp[1][0],dp[1][1],dp[1][2]) min(dp[1][0],dp[1][1],dp[1][2])

注意如果一个节点是 C C C 类型,它要变成蓝色,它的子节点不是一定要选择至少一个蓝色,也可以全都无色或者被隔离,这样子虽然这个节点是无色,我们将数值存储在蓝色里( d p [ u ] 0 ] = d p [ u ] [ 1 ] ] dp[u]0] = dp[u][1]] dp[u]0]=dp[u][1]]),这里不会影响后续的节点处理,因为把无色当成蓝色不会影响其他的转移(多建一堵墙不如直接选择 d p [ u ] [ 0 ] dp[u][0] dp[u][0]

时间复杂度: O ( n ) O(n) O(n)

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;

const int INF=0x3f3f3f3f;
const long long INFLL=1e18;

typedef long long ll;

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int t;
    std::cin >> t;
    while(t--){
        int n;
        std::cin >> n;
        std::vector<std::vector<int>> g(n + 1, std::vector<int>());
        std::string s;
        fore(i, 2, n + 1){
            int fa;
            std::cin >> fa;
            g[fa].push_back(i);
        }
        std::cin >> s;
        s = '0' + s;
        std::vector<std::vector<int>> dp(n + 1, std::vector<int>(3, INF));

        auto dfs = [&](auto self, int u) -> void {
            if(s[u] == 'P') dp[u][1] = 0;
            else if(s[u] == 'S') dp[u][2] = 0;
            else dp[u][0] = dp[u][1] = dp[u][2] = 0;
            for(auto v : g[u]){
                self(self, v);
                if(s[u] == 'P') dp[u][1] += std::min({dp[v][1], dp[v][0], dp[v][2] + 1});
                else if(s[u] == 'S')    dp[u][2] += std::min({dp[v][2], dp[v][0], dp[v][1] + 1});
                else{
                    dp[u][0] += std::min({dp[v][0], dp[v][1] + 1, dp[v][2] + 1});
                    dp[u][1] += std::min({dp[v][1], dp[v][2] + 1, dp[v][0]});
                    dp[u][2] += std::min({dp[v][2], dp[v][1] + 1, dp[v][0]});
                } 
            } 
        };

        dfs(dfs, 1);

        std::cout << std::min({dp[1][0], dp[1][1], dp[1][2]}) << endl;
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1497337.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VUE3中ArcGIS JsAPI 4.27 Map 隐藏地图黑色边框

问题&#xff1a; vue3中引入arcgis jsapi 地图加载后&#xff0c;点击地图会出现黑色边框&#xff0c;看起来很不协调 解决方案&#xff1a; 新建自定义CSS文件&#xff0c;输入一下样式内容&#xff0c;并在vue页面直接用import引入即可。 注意&#xff1a;直接写到vue页面…

C++复习笔记——泛型编程模板

01 模板 模板就是建立通用的模具&#xff0c;大大提高复用性&#xff1b; 02 函数模板 C另一种编程思想称为 泛型编程 &#xff0c;主要利用的技术就是模板 C 提供两种模板机制:函数模板和类模板 函数模板语法 函数模板作用&#xff1a; 建立一个通用函数&#xff0c;其函…

【洛谷 P8682】[蓝桥杯 2019 省 B] 等差数列 题解(数学+排序+差分)

[蓝桥杯 2019 省 B] 等差数列 题目描述 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列&#xff0c;只记得其中 N N N 个整数。 现在给出这 N N N 个整数&#xff0c;小明想知道包含这 N N N 个整数的最短的等差数列有几项&#xff1f; 输…

Mybatis-Plus:几个好的用法

项目使用mybatis-plus&#xff0c;同事的用法让我很难苟同&#xff0c;于是自己百度了一些用法&#xff0c;分享一下。 一、静态适配器 最好使用官方提供的ObjectUtils,比较全面&#xff0c;不用加载不同的对象工具。 com.baomidou.mybatisplus.core.toolkit /*** 设置查询适配…

C# 由左上、右下两个坐标点计算矩形的长、宽以及两点的距离

一、计算长、宽 直接使用坐标点计算 // 定义矩形左上角和右下角的坐标 Point topLeft new Point(0, 0); Point bottomRight new Point(5, 10); // 计算矩形的长和宽 int width bottomRight.X - topLeft.X;//矩形宽度 int height bottomRight.Y - topLeft.Y;//矩形高度或是…

实战-Sealos一键部署k8s集群-2024.3.7(测试成功)

目录 [toc] 原文链接 实战-Sealos一键部署k8s集群-2024.3.7(测试成功) | 彦 推荐文章 我的开源项目&#xff1a; 开源项目 | 彦 实验环境 centos7.6 1810,5.4.270-1.el7.elrepo.x86_64sealos v5.0.0-beta4k8s v1.28.7 &#xff08;当前时间&#xff1a;2024年3月7日 k8s最新版…

ruoyi-vue框架密码加密传输

先看一下改造后的样子&#xff0c;输入的密码不会再以明文展示。 下面我主要把前后端改造的代码贴出来。 1.后端代码 RsaUtils类 在com.ruoyi.common.utils包下新建RsaUtils类&#xff0c;RsaUtils添加了Component注解 generateKeyPair()构建密钥对添加了Bean注解 在项目启动…

AI助力剧本创作:如何5分钟内构思出热门短剧大纲

人工智能重塑短剧行业&#xff1a;从剧本创作到市场推广 在当今短剧行业的飞速发展中&#xff0c;剧本创作的质量及其更新的速度已然成为短剧能否转化为热门作品的关键性因素。然而&#xff0c;随着短剧创作成本的日益攀升&#xff0c;一个卓越的剧本无论在创作时间上还是在构思…

java中的多线程通信问题介绍

在多线程编程中&#xff0c;通信是线程间协调和同步的重要手段。由于线程是独立执行的&#xff0c;它们需要一种机制来交换信息和协调它们的行为。Java 提供了多种方式来实现线程间的通信&#xff0c;包括共享内存、消息传递、条件变量和共享对象等。 1. 共享内存 在 Java 中&a…

vue2的element UI 表格单选

代码 this.$refs.multipleTable.toggleRowSelection(selection.shift(), false);multipleTable 是定义的表格的ref

Kubernetes(K8S之存储)

configmap configMap描述信息 configMap功能在Kubernetes1.2版本中引入&#xff0c;许多应用程序会从配置文件&#xff0c;命令行参数或环境变量中读取配置信息。ConfigMap API给我们提供了向容器中注入配置信息的机制。ConfigMap可以被用来保存单个属性。 也可以用来保存整…

二叉树前序遍历函数 代码图解(先序遍历 深度优先遍历)

void PreOrder(BiTree p)//只是遍历 即只是读&#xff0c;不会改变树根 {//这个p的类型是 树的结构体 不是之前的p指针if(p!NULL){printf("%c", p->c);PreOrder(p->lchild);//函数嵌套 打印左子树PreOrder(p->rchild);//函数嵌套 打印右子树} } 同理可证 中…

如何在Win系统本地部署Jupyter Notbook交互笔记并结合内网穿透实现公网远程使用

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中&#xff0c;使用最多的无疑就是各种函数、图表、…

windows部署ruoyi-vue-pro

前提 安装java 安装maven 安装redis mysql 源代码下载 后端 ruoyi-vue-pro 前端 yudao-ui-admin-vue3 后端项目 配置maven 导入数据 CREATE DATABASE ruoyi_vue_pro;修改mysql连接配置 修改redis 打包项目 mvn clean install package -Dmaven.test.skiptrue启动YudaoSe…

Linux CentOS系统安装Spug并结合内网穿透实现远程访问本地运维平台

目录 前言 1. Docker安装Spug 2 . 本地访问测试 3. Linux 安装cpolar 4. 配置Spug公网访问地址 5. 公网远程访问Spug管理界面 6. 固定Spug公网地址 结语 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊Linux CentOS系统安装Spug并结合…

19-Java中介者模式 ( Mediator Pattern )

Java中介者模式 摘要实现范例 中介者模式&#xff08;Mediator Pattern&#xff09;提供了一个中介类&#xff0c;该类通常处理不同类之间的通信&#xff0c;并支持松耦合&#xff0c;使代码易于维护中介者模式是用来降低多个对象和类之间的通信复杂性中介者模式属于行为型模式…

快递包装展|2024上海国际电商物流包装产业展览会

2024中国(上海)国际电商物流包装产业展览会 2024 China (Shanghai) international e-commerce logistics packaging industry exhibition 时 间&#xff1a;2024年7月24日 —7月26日 地 点&#xff1a;国家会展中心&#xff08;上海市青浦区崧泽大道333号&#xff…

Vue3.0 vue.js.devtools无法显示Pinia调试工具

之前的配置方式&#xff1a; app.use(createPinia()) app.mount(#app) 更新配置方式&#xff1a; app.use(createPinia()).mount("#app") 设置之后即可显示调试工具

Python学习笔记-Flask实现简单的抽奖程序

1.导入flask包和randint包 from flask import Flask,render_template from random import randint 2.初始化 Flask 应用: app Flask(__name__) 3. 定义英雄列表 hero [黑暗之女,狂战士,正义巨像,卡牌大师,德邦总管,无畏战车,诡术妖姬,猩红收割者,远古恐惧,正义天使,无极剑…

kasan排查kernel内存越界示例(linux5.18.11)

参考资料&#xff1a; 1&#xff0c;内核源码目录中的Documentation\dev-tools\kasan.rst 2&#xff0c;KASAN - Kernel Address Sanitizer | Naveen Naidu (naveenaidu.dev) 一、kasan实现原理 KASAN&#xff08;Kernel Address SANitizer&#xff09;是一个动态内存非法访…