上海计算机学会 2023年10月月赛 乙组T4 树的覆盖(树、最小点覆盖、树形dp)

第四题:T4树的覆盖

标签:树、最小点覆盖、树形 d p dp dp
题意:求树的最小点覆盖集的大小和对应的数量,数量对 1 , 000 , 000 , 007 1,000,000,007 1,000,000,007取余数。
所谓覆盖集,是该树的点构成的集合,对树上每一条边,至少有一个顶点属于该集合。某个特定覆盖集的大小就是该集合中点的数量。
题解
第一问:最小点覆盖集的大小比较好求,也是非常经典的一个模型,和上题树形 d p dp dp差不多,对于每个节点 u u u分一下两种情况:

dp[u][0]:表示节点u属于点覆盖集,且以点u为根的子树中所连接的边都被覆盖的情况下点覆盖集中所包含最少点的个数。
dp[u][1]:表示点u不属于点覆盖集,并且以点u为根的子树中所连接的边都被覆盖的情况下点覆盖集中所包含最少点的个数。


以第二个样例举例: 4 4 4 5 5 5 6 6 6这三个节点很显然选和不选到覆盖集分别是 1 1 1 0 0 0
对于 2 2 2这个节点来说,如果选了,那么 2 2 2 5 5 5这条边,可以直接覆盖,我们加上节点 5 5 5不选的情况( d p [ 5 ] [ 1 ] dp[5][1] dp[5][1]);如果不选,那么 2 2 2 5 5 5这条边,得通过选节点 5 5 5(即加上 d p [ 5 ] [ [ 0 ] dp[5][[0] dp[5][[0])。

对应节点 3 3 3同理,然后回到节点 1 1 1来看,我们可以把节点 1 1 1选了,那么节点 2 、 3 、 4 2、3、4 234选和不选无所谓了,反正节点 1 1 1能覆盖到和他们对应的边;不选节点 1 1 1,那么节点 2 、 3 、 4 2、3、4 234都得选上(即加上 d p [ 2 ] [ 0 ] + d p [ 3 ] [ 0 ] + d p [ 4 ] [ 0 ] dp[2][0]+dp[3][0]+dp[4][0] dp[2][0]+dp[3][0]+dp[4][0])。

总结一下:

  1. 对于第一种状态 d p [ u ] [ 0 ] dp[u][0] dp[u][0],等于每个孩子节点的两种状态的最小值之和加 1 1 1,即 d p [ u ] [ 0 ] = 1 + Σ m i n ( d p [ v ] [ 0 ] , d p [ v ] [ 1 ] )   ( f a [ v ] = u ) dp[u][0]=1+Σmin(dp[v][0],dp[v][1]) \ (fa[v]=u) dp[u][0]=1+Σmin(dp[v][0],dp[v][1]) (fa[v]=u)
  2. 对于第二种状态 d p [ u ] [ 1 ] dp[u][1] dp[u][1],等于每个孩子节点的第一种状态之和,即 d p [ u ] [ 1 ] = Σ d p [ v ] [ 0 ]   ( f a [ v ] = u ) dp[u][1]=Σdp[v][0] \ (fa[v]=u) dp[u][1]=Σdp[v][0] (fa[v]=u)

第二问:求最小覆盖集的数量,对于每个节点 u u u分一下两种情况:

cnt[u][0]:表示节点u属于点覆盖集,以点u为根的子树,当前最小覆盖集的数量
cnt[u][1]:表示点u不属于点覆盖集,以点u为根的子树,当前最小覆盖集的数量
  1. c n t [ u ] [ 1 ] cnt[u][1] cnt[u][1]的状态转移方程比较好想,它的所有孩子节点都得选进覆盖集,所以对所以孩子节点的 c n t [ v ] [ 0 ] cnt[v][0] cnt[v][0]做一个乘积。即 c n t [ u ] [ 1 ] = c n t [ u ] [ 1 ] ∗ c n t [ v ] [ 0 ] cnt[u][1] = cnt[u][1] * cnt[v][0] cnt[u][1]=cnt[u][1]cnt[v][0]
  2. c n t [ u ] [ 0 ] cnt[u][0] cnt[u][0]我们得去考虑,对于孩子节点 v v v来说是选还是不选能够获得更小的覆盖集大小,如果都能,得都加起来做一个乘积;否则从更小的情况转移过来做乘积。(详情看代码部分,可以自己再推导下)

代码

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

typedef long long ll;
const ll mod = 1e9 + 7;
vector<ll> e[200005];
ll n, x, dp[200005][2], cnt[200005][2];

void dfs(ll u) {
    dp[u][0] = 1;
    dp[u][1] = 0;
    cnt[u][0] = cnt[u][1] = 1;
    for (ll i = 0; i < e[u].size(); i++) {
        ll v = e[u][i];
        dfs(v);
        if (dp[v][0] == dp[v][1]) cnt[u][0] = cnt[u][0] * (cnt[v][0] + cnt[v][1]) % mod;
        else if (dp[v][0] < dp[v][1]) cnt[u][0] = cnt[u][0] * cnt[v][0] % mod;
        else if (dp[v][0] > dp[v][1]) cnt[u][0] = cnt[u][0] * cnt[v][1] % mod;
        cnt[u][1] = cnt[u][1] * cnt[v][0] % mod;
        dp[u][0] += min(dp[v][0], dp[v][1]);
        dp[u][1] += dp[v][0];
    }
}

int main() {
    cin >> n;
    for (int i = 2; i <= n; i++) {
        cin >> x;
        e[x].push_back(i);
    }
    dfs(1);
    cout << min(dp[1][0], dp[1][1]) << endl;
    if (dp[1][0] == dp[1][1]) cout << (cnt[1][0] + cnt[1][1]) % mod << endl;
    else if (dp[1][0] < dp[1][1]) cout << cnt[1][0] % mod << endl;
    else if (dp[1][0] > dp[1][1]) cout << cnt[1][1] % mod << endl;
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue:如何通过两个点的经纬度进行距离的计算(很简单)

首先假设从api获取到了自己的纬经度和别人的纬经度 首先有一个概念需要说一下 地球半径 由于地球不是一个完美的球体&#xff0c;所以并不能用一个特别准确的值来表示地球的实际半径&#xff0c;不过由于地球的形状很接近球体&#xff0c;用[6357km] 到 [6378km]的范围值可以…

板式热交换器强度

1、不同标准中对于板换压板的规定 (1) NB/T 47004.1-2017《板式热交换器 第1部分&#xff1a;可拆卸板式热交换器》6.3压紧板6.3.3条“压紧板应有足够的刚性&#xff0c;以保证板式热交换器在正常操作状态不发生泄漏”。 (2) NB/T 47004-2009《板式热交换器》5.3紧板5.3.3条“…

Springboot+Vue项目-基于Java+MySQL的蜗牛兼职网系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

每日一题 — 串联所有单词的子串

30. 串联所有单词的子串 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;因为words里面的每一个字符串的长度都是固定的&#xff0c;所以可以将题转换成字符在字符串中的所有异位词 设出哈希表定义left和right进窗口维护count判断出窗口维护count 代码&#xff1a; …

[html]一个动态js倒计时小组件

先看效果 代码 <style>.alert-sec-circle {stroke-dasharray: 735;transition: stroke-dashoffset 1s linear;} </style><div style"width: 110px; height: 110px; float: left;"><svg style"width:110px;height:110px;"><cir…

【Qt】:界面优化(一:基本语法)

界面优化 一.基本语法1.设置指定控件样式2.设置全局控件样式3.从文件加载样式表4.使⽤Qt Designer编辑样式&#xff08;最常用&#xff09; 二.选择器1.概述2.子控件选择器3.伪类型选择器 三.盒模型 在网页前端开发领域中,CSS是一个至关重要的部分.描述了一个网页的"样式&…

快速删除node_modules依赖包的命令rimraf

1、安装rimraf npm install -g rimraf 2、使用命令删除node_modules rimraf node_modules *** window系统&#xff0c;使用命令很快就删除node_modules ***

Jmeter 场景测试:登录--上传--下载--登出

为了练习Jmeter的使用&#xff0c;今天我要测试的场景是“登录--上传--下载--登出”这样一个过程. 测试的目标是我曾经练手写的一个文件分享系统&#xff0c;它要求用户只有登录后才可以下载想要的文件。 Jmeter总体结构&#xff1a; 第一步&#xff1a;添加HTTP Cookie管理器…

微信公众号-获取用户位置

目前获取方式为&#xff0c;在用户进入公众号时&#xff0c;提示是否允许获取地理位置&#xff0c;允许后&#xff0c;将地理位置在每次进入公众号时上报给公众号。 则可以根据公众号开发文档&#xff0c;进行上报提示&#xff0c;例如引入邮件系统&#xff0c;进行管理员提示&…

vscode如何方便地添加todo和管理todo

如果想在vscode中更加方便的添加和管理TODO标签&#xff0c;比如添加高亮提醒和查看哪里有TODO标签等&#xff0c;就可以通过安装插件快速实现。 安装插件 VSCode关于TODO使用人数最多的插件是TODO Height和Todo Tree 按住 CtrlShiftX按键进入应用扩展商店&#xff0c;输入to…

Jmeter03:直连数据库

1 Jmete组件&#xff1a;直连数据库 1.1 是什么&#xff1f; 让Jmeter直接和数据库交互 1.2 为什么&#xff1f; 之前是通过接口操作数据库&#xff0c;可能出现的问题&#xff1a;比如查询可能有漏查误查的情况&#xff0c;解决方案是人工对不&#xff0c;效率低且有安全隐患…

【C++题解】1317. 正多边形每个内角的度数?

问题&#xff1a;1317. 正多边形每个内角的度数&#xff1f; 类型&#xff1a;基本运算、小数运算 题目描述&#xff1a; 根据多边形内角和定理&#xff0c;正多边形内角和等于&#xff1a;&#xff08; n&#xff0d;2 &#xff09; 180∘ ( n 大于等于 3 且 n 为整数&#…

STM32 PB3 PB4 无法作为 GPIO 使用解决办法

如下所示&#xff0c;PA13 PA14 PB3 PB4 PB5, 默认是JTAG SWD的 PIN, 需要引脚ReMap 才能作为GPIO 使用。 HAL库解决办法 // __HAL_AFIO_REMAP_SWJ_ENABLE(); //Full SWJ (JTAG-DP SW-DP):// __HAL_AFIO_REMAP_SWJ_NONJTRST(); //Full SWJ (JTAG-DP SW-DP) but without NJTR…

Spring Boot JNA 实现调用 DLL文件(清晰明了)

概述 项目需要用到 重采样算法&#xff0c;JAVA 没有现成的&#xff0c;只能通过 JNA 调用 C 的 DLL 实现&#xff0c;JNA中&#xff0c;它提供了一个动态的C语言编写的转发器&#xff0c;可以自动实现Java和C的数据类型映射。不再需要编写C动态链接库。 实现需求 根据 一个…

Python赋能AI数据分析开启人工智能新时代

文章目录 一、Python是办公自动化的重要工具二、Python是提升职场竞争力的利器三、Python是企业数字化的重要平台四、Python是AI发展的重要通道之一《编程菜鸟学Python数据分析》编辑推荐内容简介作者简介目录前言为什么要写这本书读者对象如何阅读本书 随着我国企业数字化和信…

【位运算 子集状态压缩】982按位与为零的三元组

算法可以发掘本质&#xff0c;如&#xff1a; 一&#xff0c;若干师傅和徒弟互有好感&#xff0c;有好感的师徒可以结对学习。师傅和徒弟都只能参加一个对子。如何让对子最多。 二&#xff0c;有无限多1X2和2X1的骨牌&#xff0c;某个棋盘若干格子坏了&#xff0c;如何在没有坏…

握手问题(蓝桥杯)

文章目录 握手问题【问题描述】答案&#xff1a;1204解题思路模拟 握手问题 【问题描述】 小蓝组织了一场算法交流会议&#xff0c;总共有 50 人参加了本次会议。在会议上&#xff0c;大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手&#…

Level protection and deep learning

1.模拟生成的数据 import randomdef generate_data(level, num_samples):if level not in [2, 3, 4]:return Nonedata_list []for _ in range(num_samples):# 构建指定等级的数据data str(level)for _ in range(321):data str(random.randint(0, 9))data_list.append(data)…

原型对象、实例、原型链的联系

const F function () { this.name Jack } // ƒ () { this.name Jack }const e new F() // F { name: "Jack" }console.log(e.name) // Jack 构造函数&#xff1a;现在 F 就是构造函数。任何一个函数被 new 使用后&#xff0c;就是构造函数&#xff0c;没被…

Opentelemetry——Sampling

Sampling 采样 Learn about sampling, and the different sampling options available in OpenTelemetry. 了解采样以及 OpenTelemetry 中提供的不同采样选项。 With distributed tracing, you observe requests as they move from one service to another in a distributed…
最新文章