CF1929D Sasha and a Walk in the City

简单树形动态规划。

我们把选取到的点称为黑点,由题意得,一个合法的点集能使树中任意一条简单路径上的黑点数量不超过两个。也就是说,如果黑点数量多于 \(2\),对于任意两个黑点,它们如果在同一个节点的子树内,必然是兄弟关系。否则,一旦存在祖先关系,由于黑点数量多于 \(2\),必然有一个黑点可以与这两个点组成一条黑点数量超过两个的简单路径。

设状态 \(dp_{i,j}\) 表示以 \(i\) 为根的子树内,从根到叶子节点最多经过 \(j\) 个黑点。显然,只有 \(j\) 等于 \(0,1\) 或 \(2\) 时,状态是合法的。

考虑如何转移,对于 \(dp_{i,0}\),显然等于 \(1\)。

对于 \(dp_{i,1}\),由于根到叶子节点最多经过黑点数最大值为 \(1\),最多就是两条到根的路径合并,经过 \(1+1=2\) 个黑点,所以每一个儿子内可以任意选择。另外,每个子树内还可以从没有黑点涂子树的根上的黑点变成有 \(1\) 个黑点,所以还需要加入没有黑点的方法数。根据乘法原理,可以推出如下转移式:

\[dp_{i,1}=\prod_{j\in son(i)}(dp_{j,0}+dp_{j,1})=\prod_{j\in son(i)}(1+dp_{j,1})
\]

对于 \(dp_{i,2}\),由于根到叶子节点最多经过黑点数最大值为 \(2\),所以只能有一个子树内的 \(dp\) 值可以转移来,否则必然可以构造一条黑点数量超过两个的简单路径。另外,每个子树内还可以从 \(1\) 个黑点涂子树的根上的黑点变成有 \(2\) 个黑点,所以还需要加入 \(1\) 个黑点的方法数。根据加法原理,可以推出如下转移式:

\[dp_{i,2}=\sum_{j\in son(i)}(dp_{j,1}+dp_{j,2})
\]

以 \(1\) 为整棵树的根,最后的答案为 \(dp_{1,0}+dp_{1,1}+dp_{1,2}\),也就是 \(1+dp_{1,1}+dp_{1,2}\)。

#include <bits/stdc++.h>
using namespace std;
struct edge
{
long long v,nxt;
}e[800000];
long long t,u,v,n,mod=998244353,h[800000],f[800000][3],cnt=0;
void add_edge(long long u,long long v)
{
e[++cnt].nxt=h[u];
e[cnt].v=v;
h[u]=cnt;
} void init()
{
for(int i=1;i<=n;i++)h[i]=0,f[i][1]=1,f[i][2]=0;
cnt=0;
} void dfs(long long x,long long fa)
{
for(int i=h[x];i;i=e[i].nxt)
if(e[i].v!=fa)
{
dfs(e[i].v,x);
f[x][1]=(f[x][1]*(f[e[i].v][1]+1)%mod)%mod;
f[x][2]=(f[x][2]+f[e[i].v][1]+f[e[i].v][2])%mod;
}
} int main()
{
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
init();
for(int i=1;i<=n-1;i++)
{
scanf("%lld%lld",&u,&v);
add_edge(u,v),add_edge(v,u);
}
dfs(1,0);
printf("%lld\n",(f[1][1]+f[1][2]+1)%mod);
}
return 0;
}

CF1929D Sasha and a Walk in the City 题解的更多相关文章

  1. bzoj3125: CITY 题解

    3125: CITY Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 486  Solved: 213[Submit][Status][Discuss] ...

  2. ZOJ 3195 Design the city 题解

    这个题目大意是: 有N个城市,编号为0~N-1,给定N-1条无向带权边,Q个询问,每个询问求三个城市连起来的最小权值. 多组数据 每组数据  1 < N < 50000  1 < Q ...

  3. CodeForces 821D Okabe and City

    Okabe and City 题解: 将行和列也视为一个点. 然后从普通的点走到行/列的点的话,就代表这行/列已经被点亮了. 然后将费用为0的点建上边. 注意讨论(n,m)非亮的情况下. 代码: #i ...

  4. [HIMCM暑期班]第2课:建模

    第二节课从最简单的模型开始入手:七桥问题. 首先,先去wikipedia上了解一些有关七桥问题的背景知识.http://en.wikipedia.org/wiki/Seven_Bridges_of_K ...

  5. D. Bear and Two Paths(贪心构造)

    D. Bear and Two Paths time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  6. VK Cup 2016 D. Bear and Two Paths 模拟

    D. Bear and Two Paths time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  7. Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) D. Bear and Two Paths 构造

    D. Bear and Two Paths 题目连接: http://www.codeforces.com/contest/673/problem/D Description Bearland has ...

  8. Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) D

    D. Bear and Two Paths time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  9. codeforces 673D D. Bear and Two Paths(构造)

    题目链接: D. Bear and Two Paths time limit per test 2 seconds memory limit per test 256 megabytes input ...

  10. cf公式专场-续

    Benches Time Limit:500MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Statu ...

随机推荐

  1. 详细介绍java的线程池状态

    一.详细介绍java的线程池状态 Java 中的线程池状态是 ThreadPoolExecutor 类内部管理的一个重要概念.线程池的状态决定了线程池的行为,例如是否接受新任务.是否处理队列中的任务. ...

  2. python发送QQ邮件,自定义邮件内容

    怎么发QQ邮件,网上的例子很多,就不介绍了,具体可参考:https://www.jianshu.com/p/0f8c5e4e7054 这里主要把自定义邮件内容写一下 # -*- coding: utf ...

  3. jmeter返回值作为参数传给后面的步骤使用的方法

    如,系统返回data 通过正则获取data后的数据,且名称定义为id 然后通过${id}的方式传参给需要使用的地方

  4. MySQL 在设计表(建表)时需要注意什么?

    MySQL 在设计表(建表)时需要注意的要点 设计数据库表是 MySQL 开发中非常重要的一环.合理的表结构设计可以提升性能.减少存储开销,并提高维护性.以下是一些关键的注意事项: 1. 明确需求和数 ...

  5. Tortoise-ORM级联查询与预加载性能优化

    title: Tortoise-ORM级联查询与预加载性能优化 date: 2025/04/26 12:25:42 updated: 2025/04/26 12:25:42 author: cmdra ...

  6. C#网络编程(一)----DNS/TCP/UDP协议

    简介 计算机网络是指将分布在不同地理位置的计算机系统.设备通过通信线路和设备连接起来,遵循共同的通信协议,以实现 数据传输.资源共享.协同工作 的系统 .它是现代信息技术的核心基础设施,支撑着互联网. ...

  7. 自定义Spring Authorization Server登录页

    一.鸣谢 首先要声明一些感谢: 感谢官方文档的缺失.反复造成我下面这条感谢 感谢那些胡说八道.顾彼失此的某DN文章,让我在冲向坑里的道路上一往无前 废话不多说,看剑! 本文来自:博客园-去哪里吃鱼-自 ...

  8. Vue之“表单修饰符”

    1.lazy:失去焦点时处理 案例1 2.number:限制只能输入数字 案例1 3.trim:去掉前后空格 案例1

  9. 进程间通信-POSIX 信号量

    POSIX 信号量 POSIX 信号量是一种 POSIX 标准中定义的进程间同步和互斥的方法.它允许进程之间通过信号量来实现临界区的互斥访问,从而避免竞争条件和死锁等问题. 信号量的P.V操作: P ...

  10. 关于I/O与并发

    前言 由于笔者在之前发布的一文玩转NGINX中提到过I/O复用模型,在此另起一篇文章简述相关技术. 什么是I/O I/O输入/输出(Input/Output),分为IO设备和IO接口两个部分. 在PO ...