大意:给定树, 每个点有颜色, 一个合法的边集要满足删除这些边后, 每个连通块内颜色仅有一种, 求所有合法边集的个数

$f[x][0/1]$表示子树$x$中是否还有与$x$连通的颜色

对于每种颜色已经确定了一个连通块, 连通块内部一定不能断边, 有转移

$$f[x][1]=\prod (f[y][0]+f[y][1]),f[x][0]=0$$

能断边的部分只能为不同颜色连通块间的无色结点, 有转移

$$f[x][0]=\prod (f[y][0]+f[y][1]), f[x][1]=\sum\limits_y (f[y][1]\prod\limits_{z!=y}(f[z][0]+f[z][1])) $$

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 998244353, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
//head
#ifdef ONLINE_JUDGE
const int N = 1e6+10;
#else
const int N = 111;
#endif int n, k;
vector<int> g[N], q;
int col[N], c[N], cnt[N];
int f[N][2], prod[N]; void dfs(int x, int fa) {
cnt[x] = col[x]>0;
for (int y:g[x]) if (y!=fa) {
dfs(y,x);
if (!col[x]) col[x]=col[y];
else if (col[y]&&col[x]!=col[y]) {
puts("0"), exit(0);
}
cnt[x] += cnt[y];
}
q.clear();
for (int y:g[x]) if (y!=fa) q.pb(y);
prod[0] = 1;
int sz = q.size();
REP(i,0,sz-1) {
int y = q[i];
prod[i+1]=(ll)prod[i]*(f[y][0]+f[y][1])%P;
}
if (col[x]) f[x][1]=prod[sz];
else {
f[x][0]=prod[sz];
int tmp = 1;
PER(i,0,sz-1) {
int y = q[i];
f[x][1] = (f[x][1]+(ll)tmp*f[y][1]%P*prod[i]%P)%P;
tmp = (ll)tmp*(f[y][0]+f[y][1])%P;
}
}
if (c[col[x]]==cnt[x]) cnt[x]=col[x]=0;
} int main() {
scanf("%d%d", &n, &k);
REP(i,1,n) scanf("%d", col+i);
REP(i,1,n) ++c[col[i]];
REP(i,2,n) {
int u, v;
scanf("%d%d", &u, &v);
g[u].pb(v),g[v].pb(u);
}
dfs(1,0);
printf("%d\n", f[1][1]);
}

Tree Cutting (Hard Version) CodeForces - 1118F2 (树形DP,计数)的更多相关文章

  1. POJ 2378 Tree Cutting 3140 Contestants Division (简单树形dp)

    POJ 2378 Tree Cutting:题意 求删除哪些单点后产生的森林中的每一棵树的大小都小于等于原树大小的一半 #include<cstdio> #include<cstri ...

  2. Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】

    任意门:http://codeforces.com/contest/1118/problem/F1 F1. Tree Cutting (Easy Version) time limit per tes ...

  3. Codeforces 1118 F2. Tree Cutting (Hard Version) 优先队列+树形dp

    题目要求将树分为k个部分,并且每种颜色恰好在同一个部分内,问有多少种方案. 第一步显然我们需要知道哪些点一定是要在一个部分内的,也就是说要求每一个最小的将所有颜色i的点连通的子树. 这一步我们可以将所 ...

  4. 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)

    题目: Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There ar ...

  5. Codeforces Round #277 (Div. 2)D(树形DP计数类)

    D. Valid Sets time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  6. CodeForces 219D 树形DP

    D. Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes i ...

  7. 解题:CF1118F2 Tree Cutting (Hard Version)

    题面 好题不问Div(这是Div3最后一题,不得不说Mike真是强=.=) 首先同一个颜色的点的LCA要和它们在一个划分出的块里,那么我们先按颜色把所有点到它们的LCA的路径涂色,如果这个过程中出现了 ...

  8. Codeforces 1153D 树形DP

    题意:有一个游戏,规则如下:每个点有一个标号,为max或min, max是指这个点的值是所有子节点中值最大的那一个,min同理.问如何给这颗树的叶子节点赋值,可以让这棵树的根节点值最大. 思路:很明显 ...

  9. Codeforces 1088E 树形dp+思维

    比赛的时候看到题意没多想就放弃了.结果最后D也没做出来,还掉分了,所以还是题目做的太少,人太菜. 回到正题: 题意:一棵树,点带权值,然后求k个子连通块,使得k个连通块内所有的点权值相加作为分子除以k ...

随机推荐

  1. 网络营销相关缩写名称CPM CPT CPC CPA CPS SEM SEO解析

    网络营销相关缩写名称CPM CPT CPC CPA CPS SEM SEO解析 CPM CPT CPC CPA CPS SEM SEO在网络营销中是什么意思?SEO和SEM的区别是? CPM(Cost ...

  2. WindowsServer-性能计数器

    https://jingyan.baidu.com/article/59703552e764e48fc00740dd.html

  3. switch to hexo !

    用 hexo 搭了个博客 但是由于本博客内容过多,所以对于少数内容搬迁,而且本博客和那个博客相关联,但是这个博客不再更新. 新站地址 再见!

  4. ubuntu查询某个库的相关情况

    环境:Ubuntu 14.04 64bit 1.如:查询libjpeg库的位置 ldconfig -p |grep libjpeg 2.如:查询libjpeg库的相关名称 dpkg -l '*jpeg ...

  5. Notepad++7.5.4 设置主题,使用插件

    首先官网下载 Notepad++7.5.4 默认英文转换成中文 下面设置主题: 设置-->语言格式设置 选择主题Obsidian,字体选择等宽字体Consolas,大小为11,选择全局字体,使用 ...

  6. sql:临时表和表变量

    在SQL Server的性能调优中,有一个不可比拟的问题:那就是如何在一段需要长时间的代码或被频繁调用的代码中处理临时数据集,表变量和临时表是两种选择. 临时表: 临时对象都以#或##为前缀,临时表是 ...

  7. 【第三十五章】 metrics(3)- codahale-metrics基本使用

    <!-- metrics --> <dependency> <groupId>io.dropwizard.metrics</groupId> <a ...

  8. 全面理解虚拟DOM,实现虚拟DOM

    1.为什么需要虚拟DOM DOM是很慢的,其元素非常庞大,页面的性能问题鲜有由JS引起的,大部分都是由DOM操作引起的.如果对前端工作进行抽象的话,主要就是维护状态和更新视图:而更新视图和维护状态都需 ...

  9. each遍历小结

    JQ中的遍历函数 (逐个加工函数) 格式: $(‘.box p’).each(function(index,element){ })也可以写成 $.each(‘.box p’,function(ind ...

  10. Unity3D学习笔记(十六):Animator新动画

    新动画系统: 给模型选择动画类型 普通动画:Generic 人形动画:Humanoid 建立动画控制器 - 在Project右击 - 选择Create-AnimatorContorller 将对应动画 ...