题目传送门

题解:

  先注意到一定存在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的更多相关文章

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

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

  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 Round #300 A Cutting Banner

    题目传送门 /* 贪心水题:首先,最少的个数为n最大的一位数字mx,因为需要用1累加得到mx, 接下来mx次循环,若是0,输出0:若是1,输出1,s[j]--: 注意:之前的0的要忽略 */ #inc ...

  4. 水题 Codeforces Round #300 A Cutting Banner

    题目传送门 /* 水题:一开始看错题意,以为是任意切割,DFS来做:结果只是在中间切出一段来 判断是否余下的是 "CODEFORCES" :) */ #include <cs ...

  5. 【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)

    Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2 ...

  6. BZOJ3391: [Usaco2004 Dec]Tree Cutting网络破坏

    3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 47  Solved: 37[ ...

  7. BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏( dfs )

    因为是棵树 , 所以直接 dfs 就好了... ---------------------------------------------------------------------------- ...

  8. Tree Cutting

    Tree Cutting Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others) Prob ...

  9. Problem - D - Codeforces Fix a Tree

    Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...

随机推荐

  1. GitHub 用户排行榜

    排行榜预览网址:Github | Githack | UNPKG | Gitee Github 中国用户排名,全球仓库 Star 最多排名,通过 Github API v3 来生成页面数据,排行榜预览 ...

  2. hexo的环境变量被删除怎么办

    这篇文章主要讲在path这一环境变量被删除的情况下,补上哪些环境变量才可以使hexo重新使用. 前两天配置opencv的时候,不小心将环境变量中"path"这一项中的内容给覆盖掉了 ...

  3. Java悲观锁Pessimistic-Lock常用实现场景

    1:商品库存秒杀采用悲观锁Pessimistic-Lock主要好处是安全,充分利用了数据库的性能来做的一种锁机制. 悲观锁的实现: (1)环境:mysql + jdbctemplate (2)商品表g ...

  4. js五子棋游戏代码分享

    HTML代码 <canvas id="game"></canvas> CSS代码 * { margin: 0; padding: 0; } #game { ...

  5. ASP.NET Core MVC 之区域(Area)

    区域(Area)是一个 ASP.NET MVC 功能,用于将相关功能组织为一个单独的命名空间(用于路由)和文件结构(用于视图).使用区域通过向控制器和操作添加 一个路由参数(area)来创建用于路由目 ...

  6. Go最火的Gin框架简单入门

    Gin 介绍 Gin 是一个 Golang 写的 web 框架,具有高性能的优点,,基于 httprouter,它提供了类似martini但更好性能(路由性能约快40倍)的API服务.官方地址:htt ...

  7. Linux权限管理(7)

    权限的基本介绍: rwx权限详解: rwx作用到文件: [r]:代表可读,可以读取.查看 [w]:代表可写,可以修改,但不代表可以删除该文件,删除一个文件的前提条件是对该文件所在的目录有写权限才能删除 ...

  8. **p,*p和&p使用有感

    *p两种使用情况: 1.定义指针变量,如char *p:这里p是一个变量,单单在这一点上与int a 无差别:但p这个变量特殊在其中只能存地址. 引申:对于char **p,p中存一个地址add1,a ...

  9. 阿里云部署 Flask + WSGI + Nginx 转载详解

    我采用的部署方案是: Web 服务器采用 uwsgi host Flask 用 Supervisor 引用 uwsgi 作常规启动服务 基于 Nginx 作反向代理 首先, 阿里云服务器可以通过 SS ...

  10. Mybatis 中的<![CDATA[ ]]>浅析

    在使用mybatis 时我们sql是写在xml 映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义,但我们不希望他被转义,所以我们要使用<![CDATA[ ]]&g ...