CodeForces - 1118 F2 Tree Cutting
题解:
先注意到一定存在k种颜色,切成k个块, 然后要求每个块内的颜色都一样,所以可以发现同一种颜色一定在同一个块内,故任意2个相同颜色的最短路劲上的点的颜色都是该颜色。
我们可以先把任意相同颜色点对的路径上的点的颜色都染成这个颜色。 如果发现存在一个点是已经有颜色的话,那么答案一定为0。
至于怎么颜色, 我们可以暴力往上跑,然后压缩路径,和并查集一样的道理,路过的点都染色且压缩。
这样就完成了第一部分的处理,接下来就是树DP了。
定义dp[ u ][ 0 ] 的含义是 以u为根的子树,且u还未被划入任意一种颜色的方案数。
dp[ u ][ 1 ] 的含义是 以u为根的子树,且u已被划入任意一种颜色的方案数。
那么对于有颜色的点来说,
dp[u][0] = 0;

对于没有颜色的点来说:


代码:
/*
code by: zstu wxk
time: 2019/03/02
Tags: 树DP
Problem Link: http://codeforces.com/contest/1118/problem/F2
Solve: https://www.cnblogs.com/MingSD/p/10462228.html
*/
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod = ;
const int N = 3e5 + ;
int n, k, deep[N], fa[N], col[N];
vector<int> vc[N], e1[N];
void dfs(int o, int u){
deep[u] = deep[o] + ;
fa[u] = o;
for(int v : e1[u]){
if(v == o) continue;
dfs(u, v);
}
}
bool Link(int u, int v, int k){
int tu = u, tv = v;
while(u != v){
if(deep[u] > deep[v]){
u = fa[u];
if(col[u] && col[u] != k) return false;
col[u] = k;
}
else {
v = fa[v];
if(col[v] && col[v] != k) return false;
col[v] = k;
}
}
while(tu != u){
int tt = fa[tu];
fa[tu] = u;
tu = tt;
}
while(tv != v){
int tt = fa[tv];
fa[tv] = v;
tv = tt;
}
return true;
}
LL dp[N][];
LL t1[N], t2[N], t3[N];
void DFS(int o, int u){
for(int v : e1[u]){
if(v == o) continue;
DFS(u, v);
}
if(col[u]) {
dp[u][] = ;
dp[u][] = ;
for(int v : e1[u]){
if(v == o) continue;
dp[u][] = (dp[u][] * (dp[v][] + dp[v][])) % mod;
}
}
else {
dp[u][] = ;
dp[u][] = ;
int k = e1[u].size();
if(k){
for(int i = ; i < k; ++i){
if(e1[u][i] == o)
t1[i+] = ;
else {
t1[i+] = dp[e1[u][i]][] + dp[e1[u][i]][];
dp[u][] = dp[u][] * t1[i+] % mod;
}
}
t2[] = t3[k+] = ;
for(int i = ; i <= k; ++i)
t2[i] = t1[i] * t2[i-] % mod;
for(int i = k; i >= ; --i)
t3[i] = t1[i] * t3[i+] % mod;
for(int i = ; i < k; ++i){
int v = e1[u][i];
if(v == o) continue;
dp[u][] = (dp[u][] + dp[v][] * t2[i] % mod * t3[i+] % mod) % mod;
}
}
}
}
void Ac(){
for(int i = , v; i <= n; ++i){
scanf("%d", &v);
if(v) vc[v].pb(i);
col[i] = v;
}
for(int i = , u, v; i < n; ++i){
scanf("%d%d", &u, &v);
e1[u].pb(v);
e1[v].pb(u);
}
dfs(, );
for(int i = ; i <= n; ++i){
for(int j = ; j < vc[i].size(); ++j){
if(!Link(vc[i][],vc[i][j],i)) {
puts("");
return ;
}
}
}
DFS(, );
printf("%I64d\n", dp[][]);
}
int main(){
while(~scanf("%d%d", &n, &k)){
Ac();
}
return ;
}
CodeForces - 1118 F2 Tree Cutting的更多相关文章
- Codeforces 1118 F2. Tree Cutting (Hard Version) 优先队列+树形dp
题目要求将树分为k个部分,并且每种颜色恰好在同一个部分内,问有多少种方案. 第一步显然我们需要知道哪些点一定是要在一个部分内的,也就是说要求每一个最小的将所有颜色i的点连通的子树. 这一步我们可以将所 ...
- 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 Round #300 A Cutting Banner
题目传送门 /* 贪心水题:首先,最少的个数为n最大的一位数字mx,因为需要用1累加得到mx, 接下来mx次循环,若是0,输出0:若是1,输出1,s[j]--: 注意:之前的0的要忽略 */ #inc ...
- 水题 Codeforces Round #300 A Cutting Banner
题目传送门 /* 水题:一开始看错题意,以为是任意切割,DFS来做:结果只是在中间切出一段来 判断是否余下的是 "CODEFORCES" :) */ #include <cs ...
- 【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)
Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2 ...
- BZOJ3391: [Usaco2004 Dec]Tree Cutting网络破坏
3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 47 Solved: 37[ ...
- BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏( dfs )
因为是棵树 , 所以直接 dfs 就好了... ---------------------------------------------------------------------------- ...
- Tree Cutting
Tree Cutting Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others) Prob ...
- Problem - D - Codeforces Fix a Tree
Problem - D - Codeforces Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...
随机推荐
- Hadoop MapReduce的Shuffle过程
一.概述 理解Hadoop的Shuffle过程是一个大数据工程师必须的,笔者自己将学习笔记记录下来,以便以后方便复习查看. 二. MapReduce确保每个reducer的输入都是按键排序的.系统执行 ...
- Python 使用k-means方法将列表中相似的句子聚为一类
由于今年暑假在学习一些自然语言处理的东西,发现网上对k-means的讲解不是很清楚,网上大多数代码只是将聚类结果以图片的形式呈现,而不是将聚类的结果表示出来,一下代码将老师给的代码和网上的代码结合了一 ...
- MongoDB之数据库备份与恢复
MongoDB之数据备份与恢复 一,需求 一段时间备份数据库数据,以防意外导致数据丢失 二,备份与恢复 2.1,数据库备份 1,常用命令格式 mongodump -h IP --port 端口 -u ...
- JVM实战---类加载的过程
任何程序都需要加载到内存才能与CPU进行交流 同理, 字节码.class文件同样需要加载到内存中,才可以实例化类 ClassLoader的使命就是提前加载.class 类文件到内存中 在加载类时,使用 ...
- rtags——node.js+redis实现的标签管理模块
引言在我们游览网页时,随处可见标签的身影: 进入个人微博主页,可以看到自己/他人的标签,微博系统会推送与你有相同标签的人 游览博文,大多数博文有标签标记,以说明文章主旨,方便搜索和查阅 网上购物,我们 ...
- 百度Echarts,蚂蚁金服G2,D3三种主流可视化工具对比
1.百度的Echarts 官网:https://echarts.baidu.com/ 介绍:ECharts,缩写来自Enterprise Charts,是百度推出的一款开源的,商业级数据图表,它最初是 ...
- JavaScript数据结构——图的实现
在计算机科学中,图是一种网络结构的抽象模型,它是一组由边连接的顶点组成.一个图G = (V, E)由以下元素组成: V:一组顶点 E:一组边,连接V中的顶点 下图表示了一个图的结构: 在介绍如何用Ja ...
- bootstrap实战练习中涉及的知识点(很有用哦!)
看的有关视频做的笔记,对bootstrap中涉及的知识点做了一定的解析,很有用哦!(新手上路,有不合适的地方可以指出哦!) 下面进入正题: Bootstrap是当下最流行的前端框架(界面工具集) 特点 ...
- 怎么把PicPick设置成中文版?
1.首先打开软件 2.在File文件中中点击能看到Program Options这一选项,单击打开 3.右下方有个Language选项,改成简体中文
- cs231n---生成模型
1 生成模型的定义和分类 生成模型是一种无监督学习方法.其定义是给一堆由真实分布产生的训练数据,我们的模型从中学习,然后以近似于真实的分布来产生新样本. 生成模型分为显式和隐式的生成模型: 为什么生成 ...