月之暗面(树形dp)
月之暗面
[Link](D-月之暗面_牛客练习赛97 (nowcoder.com))
题意
给一颗nnn个结点的数染色,普通染色xxx种,特殊染色yyy种,普通颜色无限制,两个相邻结点不能染相同的特殊颜色
求染色方案数
思路
先按当前结点普通颜色还是特殊颜色来分类,记f[u,0]:以u为根且u填普通颜色的方案数,f[u,1]:以u为根且u填特殊颜色的方案数f[u,0]:以u为根且u填普通颜色的方案数,f[u,1]:以u为根且u填特殊颜色的方案数f[u,0]:以u为根且u填普通颜色的方案数,f[u,1]:以u为根且u填特殊颜色的方案数,互相独立可以相加,关键在于怎么不从不漏的划分方案。
考虑维护方案对于一个点uuu与它相邻的非父亲结点viv_ivi是相互独立的互不干扰符合乘法原理。
分开来看对于uuu选000子树无限制转移为f[u,0]∗=f[vi,1]+f[vi,0]f[u,0]*=f[v_i,1] +f[v_i,0]f[u,0]∗=f[vi,1]+f[vi,0],对于uuu选111的子树当前根会限制这个子树选111的情况,f[vi][1]f[v_i][1]f[vi][1]中viv_ivi选111一共yyy种不同颜色,且无本质差别,由于uuu的存在viv_ivi只能选y−1y-1y−1种颜色,因此转移为f[u,1]∗=f[vi,0]+f[vi,1]×y−1yf[u,1]*=f[v_i,0]+f[v_i,1]\times \frac{y-1}{y}f[u,1]∗=f[vi,0]+f[vi,1]×yy−1
Code
#include <bits/stdc++.h>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 1e6 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 998244353;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int n, m, k;
int x, y;
LL f[N][2];
int qmi(int a, int b) {int res = 1;while (b) {if (b & 1) res = (LL) res * a % mod;a = (LL) a * a % mod;b >>= 1;}return res;
}
void dfs(int u, int fa) {f[u][0] = x, f[u][1] = y;for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];if (j == fa) continue ; dfs(j, u);f[u][0] = f[u][0] * (f[j][0] + f[j][1]) % mod; f[u][1] = f[u][1] * (f[j][0] + f[j][1] * k % mod) % mod;}
}
int main() {ios::sync_with_stdio(false), cin.tie(0);cin >> n >> x >> y;memset(h, -1, sizeof h);k = (LL)(y - 1) * qmi(y, mod - 2) % mod;for (int i = 1; i < n; i ++) {int u, v; cin >> u >> v;add(u, v), add(v, u);}dfs(1, -1);cout << (f[1][0] + f[1][1]) % mod << '\n';return 0;
}
因为每个点都要选一种颜色,因此f[u,0]:以u为根且u填了一个普通颜色的方案数,f[u,1]:以u为根且u了一个填特殊颜色的方案数f[u,0]:以u为根且u填了一个普通颜色的方案数,f[u,1]:以u为根且u了一个填特殊颜色的方案数f[u,0]:以u为根且u填了一个普通颜色的方案数,f[u,1]:以u为根且u了一个填特殊颜色的方案数,
则转移时候f[u,0]∗=f[vi,0]∗x+f[vi,1]∗yf[u,0]*=f[v_i,0]*x+f[v_i,1]*yf[u,0]∗=f[vi,0]∗x+f[vi,1]∗y,由于uuu选了一个因此viv_ivi只能选y−1y-1y−1个特殊颜色,所以f[u,1]∗=f[vi,0]∗x+f[vi,1]∗(y−1)f[u,1]*=f[v_i,0]*x+f[v_i,1]*(y-1)f[u,1]∗=f[vi,0]∗x+f[vi,1]∗(y−1)
Code
#include <bits/stdc++.h>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 1e6 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 998244353;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int n, m, k;
int x, y;
LL f[N][2];
void dfs(int u, int fa) {f[u][0] = 1, f[u][1] = 1;for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];if (j == fa) continue ; dfs(j, u);f[u][0] = (f[u][0] * (f[j][0] * x % mod + f[j][1] * y % mod) % mod) % mod; f[u][1] = (f[u][1] * (f[j][0] * x % mod + f[j][1] * (y - 1) % mod) % mod) % mod;}}
int main() {ios::sync_with_stdio(false), cin.tie(0);cin >> n >> x >> y;memset(h, -1, sizeof h);for (int i = 1; i < n; i ++) {int u, v; cin >> u >> v;add(u, v), add(v, u);}dfs(1, -1);cout << (f[1][0] * x + f[1][1] * y) % mod << '\n';return 0;
}
月之暗面(树形dp)相关推荐
- BNUOJ 52305 Around the World 树形dp
题目链接: https://www.bnuoj.com/v3/problem_show.php?pid=52305 Around the World Time Limit: 20000msMemory ...
- [树形dp] Jzoj P5233 概率博弈
Description 小A和小B在玩游戏.这个游戏是这样的: 有一棵n个点的以1为根的有根树,叶子有权值.假设有m个叶子,那么树上每个叶子的权值序列就是一个1->m 的排列. 一开始在1号点有 ...
- fwt优化+树形DP HDU 5909
1 //fwt优化+树形DP HDU 5909 2 //见官方题解 3 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ 4 5 #include ...
- BZOJ 1040 ZJOI2008 骑士 树形DP
题目大意:给定一个基环树林,每一个点上有权值,要求选择一个权值和最大的点集,要求点集中的随意两个点之间不能直接相连 最大点独立集--考虑到n<=100W,网络流铁定跑不了,于是我们考虑树形DP ...
- POJ 3342 树形DP+Hash
这是很久很久以前做的一道题,可惜当时WA了一页以后放弃了. 今天我又重新捡了起来.(哈哈1A了) 题意: 没有上司的舞会+判重 思路: hash一下+树形DP 题目中给的人名hash到数字,再进行运算 ...
- [NC15748]旅游 树形dp基础
菜鸡第一次接触树形dp这个东西,不过这个东西还是很好理解的(可能是因为模板题吧) 个人感觉,相比线性dp,树形dp的状态转移方程更加的直观,难点主要是在"树"的结构上比较麻烦. 题 ...
- 容斥 + 树形dp ---- 2021 icpc 沈阳 L Perfect Matchings
题目链接 题目大意: 就是给你一个2n2n2n个点的完全图,从这个图里面抽出2n−12n-12n−1条边,这些边形成一颗树,现在问你剩下的图里面点进行完美匹配有多少种方案? 解题思路: 一开始被完美匹 ...
- 树形dp ---- gym101667 A(贪心 + 树形dp + 两个dp方程组维护)
题目链接 题目大意: 就是一棵5e35e35e3的树,可以选择一些点,放上基站,如果uuu上的基站价值为ddd,那么距离uuu小于等于ddd的点都会被覆盖,问使得整棵树被覆盖需要的最小价值. 解题思路 ...
- 树形dp ---- 2018年杭电多校第二场 H travel
题目大意: 就是给你一个带点权的树,找到3条独立互不相交的路径使得权值和最大 解题思路: 很经典的树形dp 我们设dp[root][j][k]dp[root][j][k]dp[root][j][k]表 ...
- 2019 GDCPC or HDU6540 树形dp[计数dp] 详解
题目链接 题目大意: 就是给你一颗nnn个点的树,树上有mmm个关键点,你可以选择若干个关键点组成集合SSS,这个集合满足任意两点在树上的距离不超过kkk,问你有多少种选法? 解题思路: 我们考虑树形 ...
最新文章
- 编译IGSTK5.2
- android输出log,Android开发 Release情况下也能输出log
- 5年前的Dubbo,2年前的Spring Cloud,都输给了这个架构!
- .NET静态类的概念
- 为SAP Analytics Cloud的story创建持久化页面
- input 中的autoComplete属性
- 关于“携号转网” 还有许多你不知道的事
- CentOS安装mariadb做为mysql的替代品
- BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]
- 心情随笔(四):重新审视自我
- html video 笔记
- 修改Linux里的hosts文件
- mtr 检测网络 查看服务器网络是否丢包
- 图文介绍:Winhex的使用教程
- 峰会倒计时3天!硅谷传奇投资人登陆专场,围炉共话分析型数据库的爆发式增长
- 7-1 自动售货机 (30 分)
- 滴滴:去年协助警方破获25案件 成立打击黑产专项组
- php 完成时钟,PHP 绘制时钟 高洛峰 细说PHP
- 在线考勤签到打卡二维码,如何制作?
- myeclipse中导入的js文件报错(出现红叉叉,提示语法错误)
热门文章
- 乒乓球基本站姿站位和步伐
- QT 按钮保持按下时样式
- 菜鸟教程php模拟器,史上最强劲的android模拟器命令详解
- 深入理解多线程(四)— Moniter的实现原理
- MySQL技能树学习体验及期望
- Android intent.Action 参数值及对应功能介绍(转)
- phpcms 会员头像h5上传_phpcms v9前台会员中心上传头像可getshell及修复
- python蓝牙连接测试_基于python实现蓝牙通信代码实例
- java语音实现_用JAVA实现语音交互的功能(即语音聊天室的功能)
- B860AV2.1盒子刷机