P3349 [ZJOI2016]小星星
题意都需要看题解才能明白我是不是已经废了
题意就是求一个从树\(S\)到图\(T\)的映射,满足若树上的两个点有边,则它们映射在图中的两个点也连有边,且不能有多个点映射到同一个点
我们先不考虑不能有多个点映射到同一个点的限制。设\(dp[u][i]\)表示树上的\(u\)映射为图中的点\(i\)时,\(u\)的子树中合法的方案数。那么只要做一个树形dp即可,复杂度为\(O(n^3)\)
然而如果我们只是按上面那样去做,有可能会产生多个点映射到同一个点的情况。那么我们就要减去图中被映射的点只有\(n-1\)个时的情况。我们可以暴力枚举被剩下的\(n-1\)个点是哪几个,然后再做一次树形dp即可。发现有多减了\(n-2\)个点的情况...
于是不难看出这个其实就是容斥了,枚举图中被选的点,容斥处理即可
//minamoto
#include<bits/stdc++.h>
#define ll long long
#define rint register int
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
int read(){
int res,f=1;char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=25;
ll dp[N][N],res=0;bool vis[N];int ban[N],mp[N][N];
struct eg{int nx,v;}e[N];int head[N],tot,n,m;
inline void add(int u,int v){e[++tot]={head[u],v},head[u]=tot;}
void dfs(int u){
vis[u]=1;for(rint i=1;i<=n;++i)dp[u][i]=1;
for(rint i=head[u];i;i=e[i].nx){
int v=e[i].v;if(vis[v])continue;dfs(v);
for(rint j=1;j<=n;++j)if(ban[j]){
ll sum=0;
for(rint k=1;k<=n;++k)if(ban[k])sum+=dp[v][k]*mp[k][j];
dp[u][j]*=sum;
}else dp[u][j]=0;
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
for(rint i=1,u,v;i<=m;++i)u=read(),v=read(),mp[u][v]=mp[v][u]=1;
for(rint i=1,u,v;i<n;++i)u=read(),v=read(),add(u,v),add(v,u);
for(rint k=1;k<=(1<<n)-1;++k){
int sz=n;for(rint i=1;i<=n;++i)ban[i]=vis[i]=0;
for(rint i=1,p=k;p;p>>=1,++i)ban[i]=p&1,sz-=p&1;
dfs(1);ll ret=0;
for(rint i=1;i<=n;++i)ret+=dp[1][i];
sz&1?res-=ret:res+=ret;
}printf("%lld\n",res);return 0;
}
P3349 [ZJOI2016]小星星的更多相关文章
- 洛谷 P3349 [ZJOI2016]小星星 解题报告
P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...
- 【题解】P3349 [ZJOI2016]小星星 - 子集dp - 容斥
P3349 [ZJOI2016]小星星 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 小 \(Y\) 是一个心灵手巧 ...
- 【题解】Luogu P3349 [ZJOI2016]小星星
原题传送门 我们考虑设\(dp_{i,j}\)表示树上的点\(i\)在图上对应的点为\(j\)时\(i\)和子树对应在图上的方案数 \(dp_{u_i}=\prod_{v \in u.son} dp_ ...
- ZJOI2016 小星星 题解
我一生之敌是状压 本文发表于 洛谷博客:https://www.luogu.com.cn/blog/LoveMC/solution-p3349 Cnblogs:https://www.cnblogs. ...
- BZOJ 4455: [Zjoi2016]小星星 [容斥原理 树形DP]
4455: [Zjoi2016]小星星 题意:一个图删掉一些边形成一棵树,告诉你图和树的样子,求让图上的点和树上的点对应起来有多少方案 看了很多题解又想了一段时间,感觉题解都没有很深入,现在大致有了自 ...
- 4455[Zjoi2016]小星星 容斥+dp
4455: [Zjoi2016]小星星 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 527 Solved: 317[Submit][Status] ...
- [ZJOI2016]小星星&[SHOI2016]黑暗前的幻想乡(容斥)
这两道题思路比较像,所以把他们放到一块. [ZJOI2016]小星星 题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. ...
- 【BZOJ 4455】 4455: [Zjoi2016]小星星 (容斥原理+树形DP)
4455: [Zjoi2016]小星星 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 426 Solved: 255 Description 小Y是 ...
- bzoj 4455 [Zjoi2016]小星星 树形dp&容斥
4455: [Zjoi2016]小星星 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 643 Solved: 391[Submit][Status] ...
随机推荐
- Python之条件 循环和其他语句 2014-4-6
#条件 循环和其他语句 23:30pm-1:431.print和import的更多信息 使用逗号将多个表达式输出 >>> print 'age:',42 age: 42 >&g ...
- 九度教程第22题——今年暑假不AC(看尽量多的电视节目)
#define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <algorithm> using namespace ...
- Mvc系统学习9——Areas学习
在Mvc2.0中,新增加了一个特性就是Areas.在没有有使用Areas的情况下,我们的Mvc项目组织是下面这样的.当项目庞大的时候,Controllers,Model,View文件下下面势必会有很多 ...
- bzoj4504 k个串 kstring 可持久化线段树 (标记永久化)
[fjwc2015]k个串 kstring [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只 ...
- SOJ 4454 (矩阵快速幂)
先引入数的快速幂 例如计算2的5次方,常规算法2*2*2*2*2,利用快速幂的思想,求出5的二进制表达式101,权值为1和4的位上数字为1,即2^5=2^1*2^4.代码如下,时间复杂度为O(logn ...
- Layui导航、面包屑
物不在多,有用则精! 学习使用链接 导航:导航一般指页面引导性频道集合,多以菜单的形式呈现,可应用于头部和侧边,是整个网页画龙点晴般的存在.面包屑结构简单,支持自定义分隔符.千万不要忘了加载 elem ...
- hadoop(2)hadoop配置
hadoop入门(二) hadoop的配置 1.本地模式 2.伪分布式 3.分布式 一.配置linux环境: 1打开虚拟网络编辑器,选择 VMnet1 仅主机模式, 子网 IP 设为 192. ...
- LOAP& its implimenlation
LDAP 概念 LDAP的英文全称是Lightweight Directory Access Protocol,简称为LDAP,LDAP是轻量目录访问协议,LDAP是轻量目录访问协议.简单的说来,LD ...
- maven打包插件maven-shade-plugin简单介绍
作用: 1.可以把依赖打入jar包,然后直接使用这个jar包,从而不用担心依赖问题 2.通过设置MainClass,创建一个可以执行的jar包 3.Java工程经常会遇到第三方 Jar 包冲突,使用 ...
- 【转】c++中placement new操作符
new:指我们在C++里通常用到的运算符,比如A* a = new A; 对于new来说,有new和::new之分,前者位于std operator new():指对new的重载形式,它是一个函数, ...