Sandy and Nuts
题意:
现在有一个$n$个点的树形图被拆开,现在你知道其中$m$条边,已经$q$对点的$LCA$,试求原先的树有多少种可能。
解法:
考虑$dp$,$f(x,S)$表示$x$的子树内的点集为$S$(不包括$x$的方案数)
$S$被拆成$S_0 ,S_1, S_2 ... S_m$,每个集合
这样考虑$LCA(a,b) =c$,与$<x,y> ∈ E$对$dp$的影响。
前者相当于$a,b$分属于两个$S_i$,
假设$x$连向的点为$y_0,y_1...$,
后者相当于不存在$S_i$中含有两个$y_i$ 且 当$S_i$中含有一个$y_i$时,必须要将$y_i$作为$S_i - \{ y_i \}$的父节点。
这样,由于每一层要背包,还要状态压缩,代码十分的复杂。
考虑类比转二叉树的方法,$f(x,S)$ 由 $f(x,S \oplus S0) \cdot f(p, S0 \oplus p)$ 转移过来。
这样代码会简化许多。
枚举子集的时候应用 $ S_0 = S \& (S_0-1)$ 的技巧。
这样,总复杂度 $O(n*3^n + q*n*2^n )$。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector> #define N 14
#define LL long long
#define bit(x) (1<<(x)) using namespace std; int n,m,q;
int g[N];
LL f[N][<<N];
vector<int> LCA[N]; int get_bit(int S)
{
for(int i=;i<n;i++)
if(S&bit(i)) return i;
return -;
} int cnt_bit(int S)
{
int ans=;
for(;S;S>>=) if(S&) ans++;
return ans;
} bool check(int x,int S)
{
for(int i=;i<(int)LCA[x].size();i++)
if((S&LCA[x][i]) != LCA[x][i]) return ;
return ;
} LL dp(int x,int S)
{
if(f[x][S]!=-) return f[x][S];
if(!S) return f[x][S] = ;
f[x][S]=;
int t=get_bit(S);
for(int S0=S;S0;S0=(S0-)&S)
if(S0&bit(t))
{
bool flag=;
for(int i=;i<(int)LCA[x].size();i++)
if((S0&LCA[x][i]) == LCA[x][i]){flag=; break;}
if(flag || cnt_bit(g[x]&S0)>) continue;
int tmp=get_bit(g[x]&S0);
if(tmp!=-)
{
if(check(tmp,S0) && ( (S0|bit(x)) & g[tmp] ) == g[tmp])
f[x][S] += dp(x,S^S0)*dp(tmp,S0^bit(tmp));
}
else
{
for(int i=;i<n;i++)
if(S0&bit(i))
{
if(check(i,S0) && (S0&g[i]) == g[i])
f[x][S] += dp(x,S^S0)*dp(i,S0^bit(i));
}
}
}
return f[x][S];
} int main()
{
while(~scanf("%d%d%d",&n,&m,&q))
{
for(int i=;i<n;i++)
{
for(int j=;j<(<<n);j++)
f[i][j]=-;
g[i]=;
LCA[i].clear();
}
for(int i=,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
x--,y--;
g[x]|=bit(y);
g[y]|=bit(x);
}
for(int i=,x,y,z;i<=q;i++)
{
scanf("%d%d%d",&x,&y,&z);
x--,y--,z--;
LCA[z].push_back(bit(x)|bit(y));
}
cout << dp(,((<<n)-)^) << endl;
}
return ;
}
Sandy and Nuts的更多相关文章
- Codeforces 599E Sandy and Nuts(状压DP)
题目链接 Sandy and Nuts 题意大概就是给出限制条件求出在该限制条件下树的种数. #include <bits/stdc++.h> using namespace std; # ...
- CodeForces 599E Sandy and Nuts 状压DP
题意: 有一棵\(n(1 \leq n \leq 13)\)个节点的树,节点的标号为\(1 \sim n\),它的根节点是\(1\). 现在已知它的\(m(0 \leq m < n)\)条边,和 ...
- Solution -「CF 599E」Sandy and Nuts
\(\mathcal{Description}\) Link. 指定一棵大小为 \(n\),以 \(1\) 为根的有根树的 \(m\) 对邻接关系与 \(q\) 组 \(\text{LCA}\ ...
- 「算法笔记」状压 DP
一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...
- 【BZOJ-4698】Sandy的卡片 后缀数组
4698: Sdoi2008 Sandy的卡片 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 140 Solved: 55[Submit][Stat ...
- BZOJ 4698: Sdoi2008 Sandy的卡片
4698: Sdoi2008 Sandy的卡片 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 106 Solved: 40[Submit][Stat ...
- Timus 2068. Game of Nuts 解题报告
1.题目描述: 2068. Game of Nuts Time limit: 1.0 secondMemory limit: 64 MB The war for Westeros is still i ...
- sandy bridge
SANDY BRIDGE SPANS GENERATIONS Intel Focuses on Graphics, Multimedia in New Processor Design By Li ...
- ural 2068. Game of Nuts
2068. Game of Nuts Time limit: 1.0 secondMemory limit: 64 MB The war for Westeros is still in proces ...
随机推荐
- 前端学习——使用Ajax方式POST JSON数据包
0.前言 本文解释怎样使用Jquery中的ajax方法传递JSON数据包,传递的方法使用POST(当然PUT又有时也是一个不错的选择).POST JSON数据包相比标准的POST格式可读性更好 ...
- 赵雅智_Android案例_刮刮乐
实现效果 主要代码 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns ...
- Linux基础(4)-硬盘分区、格式化及文件系统的管理、软件包的管理、yum管理RPM包和python的源码安装
一: 1) 开启Linux系统前添加一块大小为15G的SCSI硬盘 2) 开启系统,右击桌面,打开终端 3) 为新加的硬盘分区,一个主分区大小为5G,剩余空间给扩展分区,在扩展分区上划分1个逻辑 ...
- LNMPA遇到504 Gateway time-out错误的解决方法
Nginx的特点是处理静态很给力,Apache的特点是处理动态很稳定,两者结合起来便是LNMPA,nginx处理前端,apache处理后端,这样处理静态会很快,处理动态会很稳定. 当我以为安装完成以后 ...
- Struts2使用POI创建Excel并下载
本文将讲解在Struts2框架下如何使用POI创建Office Excel文档并实现下载功能. Apache POI ,操作微软文档的Java API,简单来说就是可以用来操作Office文档的API ...
- Android添加系统级顶层窗口 和 WindowManager添加view的动画问题
当Dialog有编辑框时如果选择会弹菜单窗口就不要用 Context applicationContext = mainActivity.getApplicationContext(); AlertD ...
- JAVA sql语句动态参数问题
对sql语句设置动态参数 import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverMan ...
- ubuntu 12.04改变源(转载)
来源:http://blog.ubuntusoft.com/ubuntu-update-source.html#.Uq_PP9KBmxh 其它版本的修改方式相识.尽量使用原生工具来修改(见下方). 手 ...
- 第 1 章 第 2 题 空间敏感排序问题 位向量实现( bitset位向量 )
问题分析 在上篇文章中,给出了使用C语言中经典位运算符来实现位向量的方法.而本文,将介绍使用C++中的bitset容器来实现位向量的方法. 实现 // 请包含bitset头文件 #include &l ...
- 三星note3 N900刷机包 4.4.2 ZSUDNE3 官方原汁原味 稳定流畅
ROM介绍 此ROM基于最新的4.4.2 ZSUDNE3 制作,加入一些必要功能,其它性能基本与官方无差距,各方面感觉都非常不错了.此ROM本人自用,所以制作风格有点个人倾向.不论什么建议或者问题欢迎 ...