【bzoj 4455】小星星(树型DP+容斥原理+dfs建树和计算的2种方式)
题意:给一个n个点的图和一个n个点的树,求图和树上的点一一对应的方案数。(N<=17)
解法:
1.在树的结构上进行tree DP,f[i][j]表示树上点 i 对应图上点 j 时,这个点所在子树的方案数。O(n^3)。
2.我们可以发现如果按这个定义进行DP,“一 一对应”的关系挺难保证。若枚举出全排列得到对应关系,这样就C(n,n)=n! 只能拿到暴力分;那么我们就不限制“一 一对应”而改为“一对多”的关系进行tree DP,利用容斥原理达到O(2^n)的复杂度。(P.S.至于为什么用容斥原理我也不清楚,待我弄懂之后我会再更新的。 2个月后的今天 我说:“应该不会有更新了......”≡[。。]≡)
3.这题的容斥原理应用是这样的:用二进制数枚举出每次DP有哪些数没有对应的树上的点,将所有情况下的DP方案数之和按求补集的公式来求就是“所有数都一一对应树上的点”的答案。
下图中圆圈1表示数1没有对应的点的方案数,依次类推。有颜色部分是我们要求的补集。

下面附上代码——
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6
7 typedef long long LL;
8 const int N=20,M=400;
9 struct node{int x,y,next;}a[2*N];
10 int last[N],len;
11 bool v[N][N],vis[N];
12 LL f[N][N];
13 int b[N],bt;
14
15 void add(int x,int y)
16 {
17 len++;
18 a[len].x=x,a[len].y=y;
19 a[len].next=last[x],last[x]=len;
20 }
21
22 void dfs(int x,int fa)
23 {
24 /*for(int k=last[x];k;k=a[k].next)
25 {
26 int y=a[k].y;
27 if(y==fa)continue;
28 dfs(y,x);
29 }
30 for (int kk=1;kk<=bt;kk++)
31 {
32 int i=b[kk];
33 f[x][i]=1;
34 for (int k=last[x];k;k=a[k].next)
35 {
36 int y=a[k].y;
37 if (y==fa) continue;
38 LL h=0;
39 for (int kkk=1;kkk<=bt;kkk++)
40 {
41 int j=b[kkk];
42 if (v[i][j]) h+=f[y][j];
43 }
44 f[x][i]*=h;
45 }
46 }*///边建树,边不重复地DP
47 if (vis[x]) return;
48 for (int kk=1;kk<=bt;kk++)
49 {
50 int i=b[kk];
51 f[x][i]=1;
52 for (int k=last[x];k;k=a[k].next)
53 {
54 int y=a[k].y;
55 if (y==fa) continue;
56 dfs(y,x);
57 vis[y]=true;
58 LL h=0;
59 for (int kkk=1;kkk<=bt;kkk++)
60 {
61 int j=b[kkk];
62 if (v[i][j]) h+=f[y][j];
63 }
64 f[x][i]*=h;
65 }
66 }//打标记,快一点
67 }
68
69 int main()
70 {
71 int n,m;
72 scanf("%d%d",&n,&m);
73 memset(v,false,sizeof(v));
74 for (int i=1;i<=m;i++)
75 {
76 int x,y;
77 scanf("%d%d",&x,&y);
78 v[x][y]=v[y][x]=true;
79 }
80 memset(last,0,sizeof(last));
81 len=0;
82 for (int i=1;i<n;i++)
83 {
84 int x,y;
85 scanf("%d%d",&x,&y);
86 add(x,y),add(y,x);
87 }
88 LL ans=0;
89 for (int i=1;i<(1<<n);i++)
90 {
91 bt=0;
92 for (int j=1;j<=n;j++)
93 if (i&(1<<(j-1))) b[++bt]=j;
94 memset(vis,false,sizeof(vis));
95 dfs(1,0);
96 LL h=0;
97 for (int j=1;j<=bt;j++)
98 h+=f[1][b[j]];
99 if ((n-bt)%2==0) ans+=h;//按补集
100 else ans-=h;
101 }
102 printf("%lld\n",ans);
103 return 0;
104 }
【bzoj 4455】小星星(树型DP+容斥原理+dfs建树和计算的2种方式)的更多相关文章
- BZOJ 1369 Gem - 树型dp
传送门 题目大意: 给一棵树上每个点一个正权值,要求父子的权值不同,问该树的最小权值和是多少. 题目分析: 证不出来最少染色数,那就直接信仰用20来dp吧:dp[u][i]表示u节点权值赋为i时u子树 ...
- 选课 - 树型DP(孩子兄弟建树法)
题目描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了 N(N<300)门的选修课程,每个学生可选课程的数量 M 是给定的.学生选修了这M门课并考核通 ...
- BZOJ 1564 :[NOI2009]二叉查找树(树型DP)
二叉查找树 [题目描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小. 另一方面,这棵查找树中每个结点都有一个权值,每个结 ...
- BZOJ 2286 消耗战 - 虚树 + 树型dp
传送门 题目大意: 每次给出k个特殊点,回答将这些特殊点与根节点断开至少需要多少代价. 题目分析: 虚树入门 + 树型dp: 刚刚学习完虚树(好文),就来这道入门题签个到. 虚树就是将树中的一些关键点 ...
- BZOJ 1509 逃学的小孩 - 树型dp
传送门 题目大意: 在一棵树中, 每条边都有一个长度值, 现要求在树中选择 3 个点 X.Y. Z , 满足 X 到 Y 的距离不大于 X 到 Z 的距离, 且 X 到 Y 的距离与 Y 到 Z 的距 ...
- BZOJ 1864 三色二叉树 - 树型dp
传送门 题目大意: 给一颗二叉树染色红绿蓝,父亲和儿子颜色必须不同,两个儿子颜色必须不同,问最多和最少能染多少个绿色的. 题目分析: 裸的树型dp:\(dp[u][col][type]\)表示u节点染 ...
- POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断
好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...
- 洛谷P3354 Riv河流 [IOI2005] 树型dp
正解:树型dp 解题报告: 传送门! 简要题意:有棵树,每个节点有个权值w,要求选k个节点,最大化∑dis*w,其中如果某个节点到根的路径上选了别的节点,dis指的是到达那个节点的距离 首先这个一看就 ...
- 【POJ 3140】 Contestants Division(树型dp)
id=3140">[POJ 3140] Contestants Division(树型dp) Time Limit: 2000MS Memory Limit: 65536K Tot ...
随机推荐
- 想学Python不知如何入门,教你!
一.入门引导 想必有很多小伙伴想学习Python,又不知道如何入门,总觉得学习一定要头悬梁,锥刺股!NO,今天给大家分享下如何轻松入门Python! 首先,我们要学习Python,那一定要和你 ...
- C中的dll 、lib和exe文件
参考:链接1 链接2 DLL 动态链接库(Dynamic Link Library,缩写为DLL),运行时加载是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源.动态链接 ...
- Burp suite的系列介绍 (1)
前言 为了进行Web安全方面的学习,Burp suite是必备的工具之一,我们将会从多个模块进行逐步的学习. Burp suite的应用场景 1.HTTP服务端接口测试. 2.HTTP客户端和HTTP ...
- SwiftUI 官方画图实例详细解析
前言 在前面几篇关于SwiftUI的文章中,我们用一个具体的基本项目Demo来学习了下SwiftUI,里面包含了常见的一些控件使用以及数据处理和地图等等,有兴趣的小伙伴可以去翻翻以前的文章,在前面总结 ...
- CTFshow萌新赛-web签到
打开靶机 查看页面信息 可以看到有一个system函数 在Linux中可以使用":"隔离不同的语句 payload如下 https://5105c8b6-83aa-4993-91b ...
- mysql 1449 : The user specified as a definer ('usertest'@'%') does not exist 解决方法 (grant 授予权限)
从服务器上迁移数据库到本地localhost 执行 函数 时报错, mysql 1449 : The user specified as a definer ('usertest'@'%') do ...
- 细数JS中实用且强大的操作符&运算符
目录 1,前言 2,代码+应用 2.1,短路运算符 || 2.2,短路运算符 && 2.3,零合并操作符 ?? 2.4,可选链操作符 ?. 2.5,位运算符 & 和 | 2.6 ...
- Centos7 添加用户及设置权限
一.添加用户 1.登录root 用户 [gau@localhost /]$ su Password: # 输入密码 [root@localhost /]# 2.添加用户 [root@localhost ...
- Typora+PicGo+Gitee打造图床
前言 自己一直使用的是Typora来写博客,但比较麻烦的是图片粘贴上去后都是存储到了本地,写好了之后放到博客园等地,图片不能直接访问,但如今Typora已经支持图片上传,所以搞了一波图片上传到Gi ...
- TCP服务器程序
Linux下编写TCP服务器调用的函数顺序为:socket -> bind -> listen -> accept -> recv/send socket 参见:http:// ...