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,便是操作 ...
随机推荐
- iDevice取证的一大突破
近日手机取证领域传出令人震撼的消息,知名取证大厂Cellebrite宣称可破解任何版本,任何机型的iDevice,连最新的iPhone X也逃不过. 若真属实,代表着iOS的取证又重现光明.只是不确定 ...
- Unity经典游戏教程之:冒险岛
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- LR有的JMeter也有之一“参数化”
酝酿了几天,一直想写点JMeter的东西,算是对学习东西的一个整理.:) 恩,一直觉得自己领悟能力不强,别人写的东西总要看老半天也不懂.好吧!一惯的傻瓜的方式(大量的截图+参数说明)嘻嘻. 参数化:简 ...
- luogu2279_[HNOI2003]消防局的设立 贪心
传送门 不需要树形dp 关于深度排序 当前节点到最近的消防局(f[u])>2时要建新的与u的上面(v)的上面(w) 同时w的上面和上面的上面也要更新f值 #include <bits/st ...
- 【游记】NOIP2019初赛
声明 我的游记是一个完整的体系,如果没有阅读过往届文章,阅读可能会受到障碍. ~~~上一篇游记的传送门~~~ 前言 (编辑中) 文章推荐:[游记]NOIP2019复赛
- vscode中配置git
vscode中配置git vscode 报错 未找到Git.请安装Git,或在"git.path" 设置中配置 第一步安装git git安装方法自行解决,提供git下载连接! gi ...
- 洛谷 P3195 [HNOI2008]玩具装箱TOY
题意简述 有n个物体,第i个长度为ci 将n个物体分为若干组,每组必须连续 如果把i到j的物品分到一组,则该组长度为 \( j - i + \sum\limits_{k = i}^{j}ck \) 求 ...
- Javascript实现简单地发布订阅模式
不论是在程序世界里还是现实生活中,发布—订阅模式的应用都非常广泛.我们先看一下现实中的例子. 小明最近看上了一套房子,到了售楼处之后才被告知,该楼盘的房子早已售罄.好在售楼MM告诉小明,不久后还有一些 ...
- T-SQL基础语句
存储过程允许标准组件式编程(模块化设计) 存储过程能够实现快速的执行速度 存储过程能够减少网络流量 存储过程可被作为一种安全机制充分利用 在SQL Server 的系列版本中存储过程分为两类:系统提供 ...
- 最小环-Floyd
floyd求最小环 在Floyd的同时,顺便算出最小环. Floyd算法 :k<=n:k++) { :i<k:i++) :j<k:j++) if(d[i][j]+m[i][k]+m[ ...