[Educational Round 17][Codeforces 762F. Tree nesting]
题目连接:762F - Tree nesting
题目大意:给出两个树\(S,T\),问\(S\)中有多少连通子图与\(T\)同构。\(|S|\leq 1000,|T|\leq 12\)
题解:考虑树的最小表示法(有关知识可戳https://www.byvoid.com/zhs/blog/directed-tree-bracket-sequence),求出\(T\)以不同点为根时所有的子树状态
开始对树\(S\)进行\(DFS\),求出每个点的状态为\(t\)时的方案数,由于\(t\)还是由\(n\)个数字(括号序列)合并起来的,而且\(n\)不会太大,所以可以用二进制DP求解
对当前点求解时,只需遍历其儿子,将儿子的解并入当前的状态即可。由于一个点可能有若干个形状相同的子树,所以要考虑去重,具体实现见代码
- #include<bits/stdc++.h>
- using namespace std;
- #define N 1001
- #define M 1<<12
- #define MOD 1000000007
- int len(int x){return -__builtin_clz(x);}
- int Union(int x,int y){return (x<<len(y))|y;}
- struct Tree
- {
- int n,ans;
- int f[M][];
- vector<int>d[N];
- map<int,int>num[N];
- map<int,vector<int> >mp;
- void read()
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- {
- int u,v;
- scanf("%d%d",&u,&v);
- d[u].push_back(v);
- d[v].push_back(u);
- }
- }
- int dfs(int cur,int pre)
- {
- int res=;
- vector<int>tmp;
- //tmp用来记录子树的状态
- for(auto nxt:d[cur])if(nxt!=pre)
- tmp.push_back(dfs(nxt,cur));
- sort(tmp.begin(),tmp.end());
- for(auto x:tmp)res=Union(res,x);
- res<<=;
- //res表示当前节点的最小表示
- if(!mp.count(res))mp[res]=tmp;
- //将当前点对应的子树们也记录下来
- return res;
- }
- void getID()
- {
- for(int i=;i<=n;i++)
- dfs(i,);
- //枚举以所有的点为根的情况
- }
- void DP(int cur,int pre,const Tree &T)
- {
- for(auto nxt:d[cur])if(nxt!=pre)DP(nxt,cur,T);
- for(const auto &pi:T.mp)//枚举T中的所有状态
- {
- auto &types=pi.second;
- int id=pi.first,n=types.size(),now=,lst=;
- for(int i=;i<(<<n);i++)f[i][]=f[i][]=;
- f[][]=;
- //id为当前枚举到的状态,n为当前状态拥有的子树数目,用滚动数组实现儿子们的合并
- for(auto nxt:d[cur])if(nxt!=pre)
- {
- now^=,lst^=;
- for(int i=;i<(<<n);i++)
- f[i][now]=f[i][lst];
- for(int i=;i<n;i++)
- if(num[nxt][types[i]])//num[i][j]表示点i的状态为j时方案有多少个
- for(int j=(<<n)-;j>=;j--)
- if(f[j][lst] && !((<<i)&j) && !(i && types[i]==types[i-] && !((<<(i-))&j)))
- // (i && types[i]==types[i-1] && !((1<<(i-1))&j)代表的是
- //当前枚举的子树和前一个子树同构 ,且前一个子树的状态未记录
- (f[(<<i)|j][now]+=1ll*f[j][lst]*num[nxt][types[i]]%MOD)%=MOD;
- }
- if(f[(<<n)-][now])
- {
- num[cur][id]=f[(<<n)-][now];//集齐了所有子树即为对应num的答案
- if(len(id)==*T.n)(ans+=num[cur][id])%=MOD;//id的二进制长度为2m则说明一定是根节点的状态,加入答案
- }
- }
- }
- }S,T;
- int main()
- {
- S.read();
- T.read();
- T.getID();
- S.DP(,,T);
- printf("%d\n",S.ans);
- }
[Educational Round 17][Codeforces 762F. Tree nesting]的更多相关文章
- [Codeforces]762F - Tree nesting
题目大意:给出一棵n个点的树和一棵m个点的树,问第一棵树有多少个连通子树与第二棵树同构.(n<=1000,m<=12) 做法:先找出第二棵树的重心(可能为边),以这个重心为根,可以避免重复 ...
- [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]
这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...
- [Educational Round 5][Codeforces 616F. Expensive Strings]
这题调得我心疲力竭...Educational Round 5就过一段时间再发了_(:з」∠)_ 先后找了三份AC代码对拍,结果有两份都会在某些数据上出点问题...这场的数据有点水啊_(:з」∠)_[ ...
- [Educational Round 3][Codeforces 609F. Frogs and mosquitoes]
这题拖了快一周_(:з」∠)_就把这货单独拿出来溜溜吧~ 本文归属:Educational Codeforces Round 3 题目链接:609F - Frogs and mosquitoes 题目 ...
- [Educational Round 13][Codeforces 678F. Lena and Queries]
题目连接:678F - Lena and Queries 题目大意:要求对一个点集实现二维点对的插入,删除,以及询问\(q\):求\(max(x\cdot q+y)\) 题解:对每个点集内的点\(P( ...
- [Educational Round 10][Codeforces 652F. Ants on a Circle]
题目连接:652F - Ants on a Circle 题目大意:\(n\)个蚂蚁在一个大小为\(m\)的圆上,每个蚂蚁有他的初始位置及初始面向,每个单位时间蚂蚁会朝着当前面向移动一个单位长度,在遇 ...
- [Educational Round 59][Codeforces 1107G. Vasya and Maximum Profit]
咸鱼了好久...出来冒个泡_(:з」∠)_ 题目连接:1107G - Vasya and Maximum Profit 题目大意:给出\(n,a\)以及长度为\(n\)的数组\(c_i\)和长度为\( ...
- 【Henu ACM Round#17 E】Tree Construction
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 做这题之前先要知道二叉排序树的一个性质. 就是它的中序遍历的结果就是这个数组升序排序. (且每个节点的左边的节点都是比这个节点的值小 ...
- Educational Codeforces Round 17
Educational Codeforces Round 17 A. k-th divisor 水题,把所有因子找出来排序然后找第\(k\)大 view code //#pragma GCC opti ...
随机推荐
- VS Code保存使用项目Eslint规则格式化代码
One.文件-首选项-设置-选择项目 Two.打开右上角JSON设置 Three. 插入以下代码 { "eslint.options& ...
- 基于Spring Security OAuth2搭建的Spring Cloud 认证中心
Github传送门:https://github.com/13babybear/bounter-springcloud 实现功能有: 整合JWT 刷新Token 自定义客户端储存 自定义用户储存 资源 ...
- web开发-前后端分离原理
前言 前后端分离已成为互联网项目开发的业界标准使用方式,通过Nginx+Tomcat的方式(也可以中间加一个Node.js)有效的进行解耦,并且前后端分离会为以后的大型分布式架构.弹性计算架构.微服务 ...
- 4327: JSOI2012 玄武密码
4327: JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老 ...
- C# 高级编程05----常用修饰符
常用修饰符: 1.访问可见性修饰符 修饰符 应用于 说明 public 类型或成员 任何代码都可访问 protected 类型或内嵌类型的成员 只有子类能访问 internal 类型或成员 只能在包含 ...
- 论文阅读笔记四十八:Bounding Box Regression with Uncertainty for Accurate Object Detection(CVPR2019)
论文原址:https://arxiv.org/pdf/1809.08545.pdf github:https://github.com/yihui-he/KL-Loss 摘要 大规模的目标检测数据集在 ...
- OpenCV-Python-图像梯度
图像梯度 我们知道一阶导数可以用来求极值.把图片想象成连续函数,因为边缘部分的像素值与旁边的像素明显有区别,所以对图片局部求极值,就可以得到整幅图片的边缘信息.不过图片是二维的离散函数,导数就变成了差 ...
- 第三次java作业
编写“学生”类及其测试类. 5.1 “学生”类: ² 类名:Student ² 属性:姓名.性别.年龄.学号.5门课程的成绩 ² 方法1:在控制台输出各个属性的值. ² 方法2:计算平均成绩 ² 方法 ...
- Springboot @Transactional Mysql事务 无效
JPA默认创建的表是MyISAM引擎,MyISAM引擎不支持事务操作 所以需要将将数据库引擎改为InnoDB 配置修改 spring.jpa.database-platform=org.hiberna ...
- Flume-ng高可用集群负载安装与配置
1. 写在前面 flume-ng高可用长在大数据处理环节第一个出现,对于处理日志文件有很好的作用,本篇博客将详细介绍flume-ng的高可用负载均衡搭建 2. flume-ng高可用负载均衡描述 在一 ...