本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

题目链接:BZOJ4455

     UOJ185

正解: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]小星星的更多相关文章

  1. uoj185 [ZJOI2016]小星星 【dp + 容斥】

    题目链接 uoj185 题解 设\(f[i][j]\)表示\(i\)为根的子树,\(i\)号点对应图上\(j\)号点时的方案数 显然这样\(dp\)会使一些节点使用同一个节点,此时总的节点数就不满\( ...

  2. UOJ185 ZJOI2016 小星星 容斥、树形DP

    传送门 先考虑一个暴力的DP:设\(f_{i,j,S}\)表示点\(i\)映射到了图中的点\(j\),且点\(i\)所在子树的所有点映射到了图中的集合\(S\)时的映射方案数,转移暴力地枚举子集即可, ...

  3. bzoj4455 & loj2091 [Zjoi2016]小星星 容斥原理+树形DP(+状压DP?)

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4455 https://loj.ac/problem/2091 题解 很不错的一道题.(不过在当 ...

  4. BZOJ 4455: [Zjoi2016]小星星 [容斥原理 树形DP]

    4455: [Zjoi2016]小星星 题意:一个图删掉一些边形成一棵树,告诉你图和树的样子,求让图上的点和树上的点对应起来有多少方案 看了很多题解又想了一段时间,感觉题解都没有很深入,现在大致有了自 ...

  5. 4455[Zjoi2016]小星星 容斥+dp

    4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 527  Solved: 317[Submit][Status] ...

  6. [ZJOI2016]小星星&[SHOI2016]黑暗前的幻想乡(容斥)

    这两道题思路比较像,所以把他们放到一块. [ZJOI2016]小星星 题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. ...

  7. 【BZOJ 4455】 4455: [Zjoi2016]小星星 (容斥原理+树形DP)

    4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 426  Solved: 255 Description 小Y是 ...

  8. 洛谷 P3349 [ZJOI2016]小星星 解题报告

    P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...

  9. bzoj 4455 [Zjoi2016]小星星 树形dp&容斥

    4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 643  Solved: 391[Submit][Status] ...

随机推荐

  1. Oracle Instant Client的安装和使用

    转自:https://www.cnblogs.com/chinalantian/archive/2011/09/09/2172145.html 根据自己需求到Oracle网站(http://www.o ...

  2. java的poi导入excel时解析日期

    if (r.getCellType()==Cell.CELL_TYPE_NUMERIC){ if(HSSFDateUtil.isCellDateFormatted(r)){ //用于转化为日期格式 D ...

  3. JavaWeb项目(SSM)准备工作

    1.新建dynamic web project(Maven project也行) 我用的Eclipse + ssm + mysql 2.准备jar包 整合ssm的包1. springmvc: ...2 ...

  4. Python开发【第六章】:面向对象

    编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种 ...

  5. UML图箭头关系

    ML定义的关系主要有:泛化.实现.依赖.关联.聚合.组合,这六种关系紧密程度依次加强,分别看一下 泛化 概念:泛化是一种一般与特殊.一般与具体之间关系的描述,具体描述建立在一般描述的基础之上,并对其进 ...

  6. 【我的Android进阶之旅】如何隐藏Android中EditText控件的默认下划线

    Android EditText控件是经常使用的控件,但是有时候我们并不需要它的一些默认的属性,比如说下划线,因为有时候这样的默认下划线看起来特别怪异,和其他控件在一起搭配的时候不协调,因此有时候就需 ...

  7. Tensorflow神经网络进行fiting function

    使用Tensorflow中的神经网络来拟合函数(y = x ^ 3 + 0.7) # -*- coding:utf-8 -*-import tensorflow as tf import numpy ...

  8. 008-CentOS添加环境变量

    在Linux CentOS系统上安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到环境变量之前,执行“php -v”命令查看当前php版本信息时时, ...

  9. Android图片加载框架Picasso最全使用教程3

    前面我们对Picasso的用法有了一定得了解,下面就分析一下一些特殊情况下,Picasso的用法. 调用.noFade() Picasso的默认图片加载方式有一个淡入的效果,如果调用了noFade() ...

  10. git发布代码到github过程和常见错误

    在对git有了基本了解之后,并且常常看到很多人在github上发布代码和开源项目时,就会想如何也把自己的代码发布到github上,并能够不断的跟踪版本变化. 现在就有几个想要做的事. 一.如何把自己已 ...