BZOJ4455/UOJ185 [Zjoi2016]小星星
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!
题目链接:BZOJ4455
正解:DP+容斥原理
解题报告:
考虑暴力的话需要将一棵子树中的点去与另一个集合一一配对,而对于这种计数类问题,我们可以通过容斥来避开限制。
也就是说不管非法情况,用容斥的方法直接统计,最后得到答案。
我们先枚举整棵树对应的集合(一个映射),用f[i][j]表示以i为根的子树且i对应j的方案数,每次枚举根对应一个节点,再枚举每个儿子节点对应节点,乘起来就可以了。
考虑我这样做,显然会有大量节点映射到一个节点上去了,所以用容斥原理同加异减一下,把每个状态的ans综合起来就好了。
然而复杂度还是很虚,写了一发,然后被卡常了…
改变循环变量顺序,预处理可行的转移对象,终于AC了...
//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
#define RG register
const int MAXN = 19;
const int MAXM = 520;
int n,m,ecnt,first[MAXN],to[MAXM],next[MAXM],all;
int mp[MAXN][MAXN],cnt,a[MAXN];
int head[MAXN],match[MAXN];
LL ans,f[MAXN][MAXN];//f[i][j]表示以i为根的子树的方案数,其中i对应的是j
struct edge{ int to,next; }e[MAXM];
inline void link(int x,int y){ next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; }
inline void Link(int x,int y){ e[++ecnt].next=head[x]; head[x]=ecnt; e[ecnt].to=y; }
inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void dp(RG int x,RG int fa){
RG int i,s1,j,k; for(i=first[x];i;i=next[i]) { if(to[i]==fa) continue; dp(to[i],x); }
RG LL now=0;
for(s1=1;s1<=cnt;++s1) {//枚举当前子树的根选什么
f[x][s1]=1;
for(j=first[x];j;j=next[j]) {
if(to[j]==fa) continue; now=0;
for(k=head[a[s1]];k;k=e[k].next) now+=f[to[j]][ match[e[k].to] ];
f[x][s1]*=now;
if(f[x][s1]==0) break;//剪枝...
}
}
} inline void work(){
n=getint(); m=getint(); all=(1<<n)-1; RG int i,j,x,y; RG LL now;
for(i=1;i<=m;++i) { x=getint(); y=getint(); mp[x][y]=mp[y][x]=1; }
for(i=1;i<n;++i) { x=getint(); y=getint(); link(x,y); link(y,x); }
for(i=1;i<=all;++i) {
x=i; cnt=0;
for(j=1;j<=n;++j) {
if(x&1) a[++cnt]=j; match[j]=cnt;
x>>=1; if(x==0) break;
}
ecnt=0; memset(head,0,sizeof(head));
for(j=1;j<=cnt;j++)
for(y=1;y<=cnt;y++)
if(mp[ a[j] ][ a[y] ])
Link(a[j],a[y]); dp(1,0);
now=0;
for(j=1;j<=cnt;++j) now+=f[1][j]; if((cnt&1) == (n&1)) ans+=now;
else ans-=now;
}
printf("%lld",ans);
} int main()
{
work();
return 0;
}
BZOJ4455/UOJ185 [Zjoi2016]小星星的更多相关文章
- uoj185 [ZJOI2016]小星星 【dp + 容斥】
题目链接 uoj185 题解 设\(f[i][j]\)表示\(i\)为根的子树,\(i\)号点对应图上\(j\)号点时的方案数 显然这样\(dp\)会使一些节点使用同一个节点,此时总的节点数就不满\( ...
- UOJ185 ZJOI2016 小星星 容斥、树形DP
传送门 先考虑一个暴力的DP:设\(f_{i,j,S}\)表示点\(i\)映射到了图中的点\(j\),且点\(i\)所在子树的所有点映射到了图中的集合\(S\)时的映射方案数,转移暴力地枚举子集即可, ...
- bzoj4455 & loj2091 [Zjoi2016]小星星 容斥原理+树形DP(+状压DP?)
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4455 https://loj.ac/problem/2091 题解 很不错的一道题.(不过在当 ...
- 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是 ...
- 洛谷 P3349 [ZJOI2016]小星星 解题报告
P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...
- bzoj 4455 [Zjoi2016]小星星 树形dp&容斥
4455: [Zjoi2016]小星星 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 643 Solved: 391[Submit][Status] ...
随机推荐
- fnt 图字原理
摘自:http://blog.csdn.net/wzq9706/article/details/8188256 首先要介绍一下,图字是怎么来的?其实这个很早很早了,记得80后在95年开始玩DOS下的仙 ...
- cocos2d-X学习之主要类介绍:精灵角色(CCSprite)
CCSprite是一副2D图像,CCSprite可以通过图像或者图像中的一个矩形子区域创建 如果它的父节点或者任意继承树上的节点是CCspriteBatchNode则具有下述特性: 父节点是CCSpr ...
- linux禁用触摸板驱动
Method 1: 终端输入如下命令: sudo modprobe -r psmouse 如果打开触摸板就是: sudo modprobe psmouse ------- Method 2: 第一步: ...
- 高性能Web开发系列
1. 高性能WEB开发基础 http://www.uml.org.cn/net/201404225.asp 2. 高性能WEB开发进阶(上) http://www.uml.org.cn/net/201 ...
- Centos6.5 DNS配置
服务器端:192.168.186.130 1.安装 # yum -y install bind* 2.主要配置文件 [root@localhost named]# vim /etc/named.con ...
- 6.javaScript中的二维数组
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Java 常用语法和数据结构
Collection 首先Java中的collection都是支持泛型和类型安全 由于Java单根继承, 所以不指定, 可以在collection里面放任何对象, collection会都当作obje ...
- for...of 与 for...in 区别
一.for...of 1.定义 for...of 语句遍历可迭代对象(包括数组.Set 和 Map 结构.arguments 对象.DOM NodeList 对象.字符串等). 2.语法 for (v ...
- php中get_cfg_var()和ini_get()的用法及区别
php里get_cfg_var()和ini_get()都是取得配置值的函数,当你需要获取php.ini里的某个选项的配置值时,这两个函数都都可以使用,得到的结果是一样的. 不过,get_cfg_var ...
- 我的Android进阶之旅------>关于使用CSDN-markdown编辑器来编写博客
关于使用MarkDown编辑器的原因 什么是 Markdown 制作一份待办事宜 Todo 列表 书写一个质能守恒公式LaTeX 高亮一段代码code 高效绘制 流程图 高效绘制序列图 绘制表格 更详 ...