[BZOJ4455][ZJOI2016]数星星(容斥DP)
4455: [Zjoi2016]小星星
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 707 Solved: 419
[Submit][Status][Discuss]Description
小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品。她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星。有一天她发现,她的饰品被破坏了,很多细线都被拆掉了。这个饰品只剩下了n?1条细线,但通过这些细线,这颗小星星还是被串在一起,也就是这些小星星通过这些细线形成了树。小Y找到了这个饰品的设计图纸,她想知道现在饰品中的小星星对应着原来图纸上的哪些小星星。如果现在饰品中两颗小星星有细线相连,那么要求对应的小星星原来的图纸上也有细线相连。小Y想知道有多少种可能的对应方式。只有你告诉了她正确的答案,她才会把小饰品做为礼物送给你呢。Input
第一行包含个2正整数n,m,表示原来的饰品中小星星的个数和细线的条数。接下来m行,每行包含2个正整数u,v,表示原来的饰品中小星星u和v通过细线连了起来。这里的小星星从1开始标号。保证u≠v,且每对小星星之间最多只有一条细线相连。接下来n-1行,每行包含个2正整数u,v,表示现在的饰品中小星星u和v通过细线连了起来。保证这些小星星通过细线可以串在一起。n<=17,m<=n*(n-1)/2Output
输出共1行,包含一个整数表示可能的对应方式的数量。如果不存在可行的对应方式则输出0。Sample Input
4 3
1 2
1 3
1 4
4 1
4 2
4 3Sample Output
6HINT
Source
一个很好理解的题解:https://blog.csdn.net/johann_oier/article/details/51090513
思路就是:如果集合可重,那么我们对于以i为根的子树,直接枚举这些节点的集合,然后f[i][j]表示i映射到原图的j的方案数。
那么现在集合不可重怎么办呢?去掉这个限制的一个好办法就是容斥,显然最后整棵树对应的集合是全集,那么我们将映射集合为全集的方案数-映射集合大小为n-1的方案数+大小为n-2的方案数-...,最后就是答案了。
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
ll f[N][N];
int n,m,ed,x,y,cnt,hash[N],g[N][N],mp[N][N],fa[N],p[N],q[N],h[N],to[N],nxt[N];
void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } void bfs(int s){
int l=,r=; q[]=s;
while (l<=r){
int x=q[l],c=; l++;
rep(i,,n) if (mp[x][i] && i!=fa[x]) q[++r]=i,fa[i]=x,++c,add(x,i);
if (!c) hash[x]=;
}
} void dp(int s,int sta,int cnt){
for (int i=n; i; i--){
int x=q[i];
if (hash[x]) continue;
rep(j,,cnt){
for (int i=h[x],k; i; i=nxt[i])
if (fa[k=to[i]]==x){
ll sm=;
rep(l,,cnt) if (g[p[j]][p[l]]) sm+=f[k][l];
f[x][j]*=sm;
}
}
}
} int get(int x){
int cnt=;
for (int j=; x; x>>=,j++) if (x & ) p[++cnt]=j; x>>=;
return cnt;
} int main(){
freopen("bzoj4455.in","r",stdin);
freopen("bzoj4455.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,,n) g[i][i]=;
rep(i,,m) scanf("%d%d",&x,&y),g[x][y]=g[y][x]=;
rep(i,,n-) scanf("%d%d",&x,&y),mp[x][y]=mp[y][x]=;
bfs(); ll ans=; int tag=n&;
for (int sta=; sta<(<<n); sta++){
int cnt=get(sta);
ll flag=((cnt&)==tag)?:-,s=;
rep(i,,n) rep(j,,cnt) f[i][j]=;
dp(,sta,cnt);
rep(i,,cnt) s+=f[][i];
ans+=flag*s;
}
printf("%lld\n",ans);
return ;
}
[BZOJ4455][ZJOI2016]数星星(容斥DP)的更多相关文章
- 「LOJ2091」「ZJOI2016」小星星 容斥+DP
题目描述 小 Y 是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用 \(m\)条彩色的细线串了起来,每条细线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉 ...
- [ZJOI2016]小星星(容斥+dp)
洛谷链接:https://www.luogu.org/problemnew/show/P3349 题意相当于给一棵树重新赋予彼此不同的编号,要求树上相邻的两个节点在给定的另外一个无向图中也存在边相连. ...
- [zjoi2016]小星星 (容斥+DP)
我们先用树形DP,求出选取集合S中的点,满足连通性的但是标号可重的方案数,贡献给F(i)(1\(\leq\)i\(\leq\)\(\mid S\mid\)),也就是我们要处理出F(i)代表取至多i个点 ...
- HDU 5794 A Simple Chess (容斥+DP+Lucas)
A Simple Chess 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 Description There is a n×m board ...
- 【XSY3156】简单计数II 容斥 DP
题目大意 定义一个序列的权值为:把所有相邻的相同的数合并为一个集合后,所有集合的大小的乘积. 特别的,第一个数和最后一个数是相邻的. 现在你有 \(n\) 种数,第 \(i\) 种有 \(c_i\) ...
- [CF1086E]Beautiful Matrix(容斥+DP+树状数组)
给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...
- 【BZOJ3622】已经没有什么好害怕的了 容斥+DP
[BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...
- $bzoj2560$ 串珠子 容斥+$dp$
正解:容斥+$dp$ 解题报告: 传送门$QwQ$ $umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多 ...
- 洛谷P5206 [WC2019]数树 [容斥,DP,生成函数,NTT]
传送门 Orz神仙题,让我长了许多见识. 长式子警告 思路 y=1 由于y=1时会导致后面一些式子未定义,先抓出来. printf("%lld",opt==0?1:(opt==1? ...
随机推荐
- 【BZOJ】1914: [Usaco2010 OPen]Triangle Counting 数三角形
[题意]给定坐标系上n个点,求能构成的包含原点的三角形个数,n<=10^5. [算法]极角排序 [题解]补集思想,三角形个数为C(n,3)-不含原点三角形. 将所有点极角排序. 对于一个点和原点 ...
- shell 给未定义的变量设定默认值 ${parameter:-word}
参考: [ Unix & Linux ] Shell Demo $echo ${JENKINS_VERSION:-2.7.4} 2.7.4 $JENKINS_VERSION=2.99 $ech ...
- 【洛谷 P4934】 礼物 (位运算+DP)
题目链接 位运算+\(DP\)=状压\(DP\)?(雾 \(a\&b>=min(a,b)\)在集合的意义上就是\(a\subseteq b\) 所以对每个数的子集向子集连一条边,然后答案 ...
- 【HNOI】d 最小割
[题目大意]给定一个n*m的土地,每块可以种a或b作物,每种作物在不同的位置有不同的收成,同时,有q个子矩阵中,全部种指定的作物(a或b)会有一定的加成收成,求最大收成. [数据范围] 50% n,m ...
- Eclipse连接海马模拟器
找到海马模拟器安装目录: 使用cmd 命令进入命令行:D: cd:D:\Program Files (x86)\Droid4X 进入模拟器所在目录 运行adb connect 127.0.0.1:26 ...
- 【遍历集合】Java遍历List,Map,Vector,Set的几种方法
关于list,map,set的区别参考http://www.cnblogs.com/qlqwjy/p/7406573.html 1.遍历list @Test public void testList( ...
- bugku逗号过滤注入
URL:http://120.24.86.145:8002/web15/ 直接给出了源码: <?php error_reporting(0); function getIp(){ $ip = ' ...
- redis可编译
redis-3.0.7 可编译 redis-3.0.7.tar.gz twemproxy-master.zip keepalived-1.2.19.tar.gz openssl-1.0.1s.tar. ...
- [ python ] 类的组合
首先,使用面向对象是一个人狗大战的实例: class Person: def __init__(self, name, hp, aggr, sex): self.name = name self.hp ...
- Android各层推荐开发书籍及参考资料!!!
Android各层推荐开发书籍及参考资料 转自:http://blog.csdn.net/fancylovejava/article/details/8657058 Android系统按照架构来说一共 ...