Tree Cutting (Hard Version) CodeForces - 1118F2 (树形DP,计数)
大意:给定树, 每个点有颜色, 一个合法的边集要满足删除这些边后, 每个连通块内颜色仅有一种, 求所有合法边集的个数
$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,计数)的更多相关文章
- POJ 2378 Tree Cutting 3140 Contestants Division (简单树形dp)
POJ 2378 Tree Cutting:题意 求删除哪些单点后产生的森林中的每一棵树的大小都小于等于原树大小的一半 #include<cstdio> #include<cstri ...
- 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 ...
- Codeforces 1118 F2. Tree Cutting (Hard Version) 优先队列+树形dp
题目要求将树分为k个部分,并且每种颜色恰好在同一个部分内,问有多少种方案. 第一步显然我们需要知道哪些点一定是要在一个部分内的,也就是说要求每一个最小的将所有颜色i的点连通的子树. 这一步我们可以将所 ...
- 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)
题目: Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There ar ...
- 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 ...
- CodeForces 219D 树形DP
D. Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes i ...
- 解题:CF1118F2 Tree Cutting (Hard Version)
题面 好题不问Div(这是Div3最后一题,不得不说Mike真是强=.=) 首先同一个颜色的点的LCA要和它们在一个划分出的块里,那么我们先按颜色把所有点到它们的LCA的路径涂色,如果这个过程中出现了 ...
- Codeforces 1153D 树形DP
题意:有一个游戏,规则如下:每个点有一个标号,为max或min, max是指这个点的值是所有子节点中值最大的那一个,min同理.问如何给这颗树的叶子节点赋值,可以让这棵树的根节点值最大. 思路:很明显 ...
- Codeforces 1088E 树形dp+思维
比赛的时候看到题意没多想就放弃了.结果最后D也没做出来,还掉分了,所以还是题目做的太少,人太菜. 回到正题: 题意:一棵树,点带权值,然后求k个子连通块,使得k个连通块内所有的点权值相加作为分子除以k ...
随机推荐
- linux常用命令:ip 命令
ip命令是Linux下较新的功能强大的网络配置工具. 1.命令格式: ip [OPTIONS] OBJECT [COMMAND [ARGUMENTS]] 2.命令功能: ip命令用来显示或操纵L ...
- ACM题目————中位数
题目描述 长为L的升序序列S,S[L / 2]为其中位数. 给出两个等长升序序列S1和S2,求两序列合并并排序后的中位数. 输入 多组数据,每组第一行为n,表示两个等长升序序列的长度. 接下来n行为升 ...
- 深入理解kafka
摘自: <kafka权威指南> 集群间成员关系 Kafka 使用Zoo keeper 来维护集群成员的信息.每个broker 都有一个唯一标识符,这个标识符可以在配置文件里指定,也可以自动 ...
- JQuery判断input是否被禁用
<script src="jquery.min.js"></script> <br/><input type="text&quo ...
- 02:Django进阶篇
目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...
- this逃逸
首先,什么是this逃逸? this逃逸是指类构造函数在返回实例之前,线程便持有该对象的引用. 常发生于在构造函数中启动线程或注册监听器. eg: public class ThisEscape { ...
- MVC 视图的简单学习
视图学习第一阶段:http://www.cnblogs.com/meetyy/p/3464432.html 视图学习第二阶段:http://www.cnblogs.com/meetyy/p/34665 ...
- JavaScript 题目
1. ],b=a; b[]=; console.log(a+b); a=[], b=a, b=[]; console.log(a+b); 2.快速排序法 var quickSort = functio ...
- 筛选出sql 查询结果中 不包含某个字符
select * from table1 where patindex('%关键字%' , aa) = 0 select * from table1 where charindex('关键字' , a ...
- Unity3D学习笔记(三):V3、运动、帧率、OnGUI
盯着看:盯住一个点 transform.LookAt(Vector3 worldPosition); using System.Collections; using System.Collection ...