CF461B Appleman and Tree题解
创始人
2024-02-05 20:14:12
0

洛谷题面
在这里插入图片描述
感觉是非常经典的一道题,最近好像总是见到,今天也算给它做了,发一篇题解来记录一下。

这道题是一道树形 DP 题,设 f[u][0/1]f[u][0/1]f[u][0/1] 表示 uuu 点属于一个无黑点 /// 有且仅有一个黑点的联通块时的方案数。我们考虑如何进行转移。

对于 f[u][1]f[u][1]f[u][1],我们考虑如果 uuu 在一个有且仅有一个黑点的联通块时,对于它的儿子 vvv,有三种情况:

  1. 儿子是不合法的,那么我们需要把儿子和 uuu 放在一个联通块里,也就是儿子要贴着父亲,对应的贡献是f[u][1]×f[v][0]f[u][1] \times f[v][0]f[u][1]×f[v][0]。
  2. 儿子是合法的,那么我们可以从中间断开,对应的贡献是 f[u][1]×f[v][1]f[u][1] \times f[v][1]f[u][1]×f[v][1]。
  3. 父亲是不合法的,那么需要把 uuu 和它的儿子放到一个联通块里,对应的贡献是 f[u][0]×f[v][1]f[u][0] \times f[v][1]f[u][0]×f[v][1]。

所以对于 f[u][1]f[u][1]f[u][1] 的转移就是 f[u][1]=f[u][1]×(f[v][0]+f[v][1])+f[u][0]×f[v][1]f[u][1] = f[u][1] \times (f[v][0] + f[v][1]) + f[u][0] \times f[v][1]f[u][1]=f[u][1]×(f[v][0]+f[v][1])+f[u][0]×f[v][1]。

对于 f[u][0]f[u][0]f[u][0],有两种情况:

  1. 父亲不合法的同时,儿子也不合法,那么把父亲和儿子放在一起,对应的贡献是 f[u][0]×f[v][0]f[u][0] \times f[v][0]f[u][0]×f[v][0]。
  2. 父亲不合法,但儿子合法,那么就从中间断开,对应的贡献是 f[u][0]×f[v][1]f[u][0] \times f[v][1]f[u][0]×f[v][1]。

所以对于 f[u][0]f[u][0]f[u][0] 的转移就是 f[u][0]=f[u][0]×(f[v][0]+f[v][1])f[u][0] = f[u][0] \times (f[v][0] + f[v][1])f[u][0]=f[u][0]×(f[v][0]+f[v][1])。

初始的状态是 f[u][color[u]]=1f[u][color[u]] = 1f[u][color[u]]=1,最后的答案如果以 111 为根的话就是 f[1][1]f[1][1]f[1][1]。

#include 
#define ll long long
#define drep(a,b,c) for(int a(b) ; a>=(c) ; --a)
#define rep(a,b,c) 	for(int a(b) ; a<=(c) ; ++a)
using namespace std;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
}
inline void print(int x){if(x < 0) putchar('-'),x = -x;if(x >= 10) print(x / 10);putchar(x % 10 + '0');
}
const int M = 2e5+10;
const int mod = 1e9+7;
int n,cnt;
int head[M],col[M];
ll f[M][2];
struct Edge{int to,nxt;
}e[M<<1];
inline void add(int u,int v){e[++cnt].to = v;e[cnt].nxt = head[u];head[u] = cnt;
}
void dfs(int u,int fa){f[u][col[u]] = 1;for(int i(head[u]) ; i ; i=e[i].nxt){int v = e[i].to;if(v == fa) continue;dfs(v,u);f[u][1] = f[u][1] * f[v][1] % mod + f[u][1] * f[v][0] % mod + f[u][0] * f[v][1] % mod;f[u][0] = f[u][0] * f[v][0] % mod + f[u][0] * f[v][1] % mod;f[u][1] %= mod;f[u][0] %= mod;}
}
signed main(){n = read();rep(i,2,n){int u = read() + 1;add(u,i),add(i,u);}rep(i,1,n) col[i] = read();dfs(1,0);printf("%lld\n",f[1][1]);return 0;
}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...