[CC-BLREDSET]Black and Red vertices of Tree

题目大意:

有一棵\(n(\sum n\le10^6)\)个结点的树,每个结点有一种颜色(红色、黑色、白色)。删去一个由红色点构成的连通块,使得存在一个黑点和一个白点,满足这两个点不连通。问有多少种删法。

思路:

设满足删掉这个点后,使得存在一个黑点和一个白点,满足这两个点不连通的红点为关键点。那么我们可以用两个\(\mathcal O(n)\)的树形DP求出所有的关键点。剩下的问题就变成了求有多少种全红连通块使得该连通块中至少有一个关键点,这显然又可以用一个\(\mathcal O(n)\)树形DP求出。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=1e5+1,mod=1e9+7;
bool mark[N];
int col[N],cnt1[N],cnt2[N],f[N][2];
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
void dfs(const int &x,const int &par) {
cnt1[x]=cnt2[x]=0;
if(col[x]==1) cnt1[x]=1;
if(col[x]==2) cnt2[x]=1;
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x);
cnt1[x]+=cnt1[y];
cnt2[x]+=cnt2[y];
}
}
void move(const int &x,const int &par) {
bool g1=false,g2=false;
if(x!=1) {
g1=cnt1[par]-cnt1[x];
g2=cnt2[par]-cnt2[x];
cnt1[x]+=cnt1[par]-cnt1[x];
cnt2[x]+=cnt2[par]-cnt2[x];
}
mark[x]=false;
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
mark[x]|=cnt1[y]&&g2;
mark[x]|=cnt2[y]&&g1;
g1|=cnt1[y];
g2|=cnt2[y];
move(y,x);
}
}
void dp(const int &x) {
col[x]=-1;
f[x][mark[x]]=1;
f[x][!mark[x]]=0;
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(col[y]) continue;
dp(y);
f[x][1]=(1ll*f[x][1]*(f[y][0]+f[y][1]+1)%mod+1ll*f[x][0]*f[y][1]%mod)%mod;
f[x][0]=1ll*f[x][0]*(f[y][0]+1)%mod;
}
}
int main() {
for(register int T=getint();T;T--) {
const int n=getint();
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
for(register int i=1;i<=n;i++) {
col[i]=getint();
}
dfs(1,0);
move(1,0);
for(register int i=1;i<=n;i++) {
if(!col[i]) dp(i);
}
for(register int i=1;i<=n;i++) {
e[i].clear();
}
int ans=0;
for(register int i=1;i<=n;i++) {
if(col[i]==-1) (ans+=f[i][1])%=mod;
}
printf("%d\n",ans);
}
return 0;
}

[CC-BLREDSET]Black and Red vertices of Tree的更多相关文章

  1. BNUOJ 26229 Red/Blue Spanning Tree

    Red/Blue Spanning Tree Time Limit: 2000ms Memory Limit: 131072KB This problem will be judged on HDU. ...

  2. CF375E Red and Black Tree(线性规划)

    CF375E Red and Black Tree(线性规划) Luogu 题解时间 很明显有一个略显复杂的 $ n^3 $ dp,但不在今天讨论范围内. 考虑一些更简单的方法. 设有 $ m $ 个 ...

  3. [Codeforces375E]Red and Black Tree

    Problem 给定一棵有边权的树.树上每个点是黑或白的.黑白点能两两交换. 求符合任意一个白点到最近黑点的距离小于等于x时,黑白点交换次数最少为多少. Solution 明显是一题树形DP.我们先跑 ...

  4. [CodeForces-375E]Red and Black Tree

    题目大意: 给你一棵带边权的树,每个结点可能是红色或者黑色,你可以交换若干个点对使得任意一个红点到达与其最近的黑点的距离小于等于m. 思路: 动态规划. f[i][j][k]表示以i为根的子树中,连向 ...

  5. 「CF375E」Red and Black Tree「树形DP」

    题意 给定一个结点颜色红或黑的树,问最少进行多少次交换黑.红结点使得每个红结点离最近的黑结点距离\(\leq x\). \(1\leq n \leq 500, 1 \leq x \leq 10^9\) ...

  6. 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)

    BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among ...

  7. ACM-ICPC2018 青岛赛区网络预赛-B- Red Black Tree

    题目描述 BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. A ...

  8. 1443. Minimum Time to Collect All Apples in a Tree

    Given an undirected tree consisting of n vertices numbered from 0 to n-1, which has some apples in t ...

  9. easyui 键盘控制tree 上下

    $.extend($.fn.tree.methods, { highlight: function(jq, target){ return jq.each(function(){ $(this).fi ...

随机推荐

  1. .net C# 抽奖,中奖

    demo设置了8个奖项,每个奖项可以自定义中奖率,精度为1/10000 public string PrizeDraw() { //奖品以及中奖率 const string prizeString = ...

  2. 字符转ASCII码

    char k = '成'; int str = (int)k; Console.WriteLine(str); 结果25104就是‘成’对应的ASCII值

  3. 解决OS睡眠功能中,移动鼠标就会唤醒

    设备管理器,在相应项目上右键属性.

  4. Hadoop java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils

    .jar 学习好友推荐案例的时候,提交运行时报错找不到StringUtils java.lang.ClassNotFoundException: org.apache.commons.lang3.St ...

  5. mysql如何添加一个表的外键

    1:创建一个父表,主键作为子表的外键: create table province( pId int primary key auto_increment, pName varchar() ); 2: ...

  6. sprintf补位

    有的时候需要00001这样的字符串 来源却是Int的1 这个时候就可以用sprintf方法了 $i = 3; $a=sprintf("%08d", $i); echo $a; %0 ...

  7. 【Android】android:windowSoftInputMode属性详解

    activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性. 这个属性能影响两件事情: [一]当有焦点产生时,软键盘是隐藏还是显示 [二]是否减少活动 ...

  8. 关于mac的一些常用操作记录

    之前记录过一个关于mac远程连接window机,实现共享文件的记录,今天记录一些常用的操作,会持续更新. 1.谷歌浏览器 f12的操作 command+option+i 打开调试面板 2.打开指定位置 ...

  9. js去掉前后空格

    //去前后空格 data=data.replace(/(^\s*)|(\s*$)/g, "");

  10. crc循环冗余检验

    CRC(Cyclic Redundancy Check):循环冗余检验.在链路层被广泛使用的检错技术. CRC原理: 1.发送端 1.1.在发送端先将数据分组,每组k个数据.假定要传送的数据是M. 1 ...