[CSP-S模拟测试]:巨神兵(状压DP)
题目描述
欧贝利斯克的巨神兵很喜欢有向图,有一天他找到了一张$n$个点$m$条边的有向图。
欧贝利斯克认为一个没有环的有向图是优美的,请问这张图有多少个子图(即选定一个边集)是优美的?答案对$1,000,000,007$取模。
输入格式
第一行两个整数$n$和$m$。
接下来$m$行每行两个整数表示一条有向边。保证无重边无自环。
输出格式
一行一个整数表示答案,对$1,000,000,007$取模。
样例
样例输入:
3 6
1 2
2 1
1 3
3 1
2 3
3 2
样例输出:
25
数据范围与提示
对于$40\%$的数据$n\leqslant 5,m\leqslant 20$;
对于$60\%$的数据$n\leqslant 10$;
对于$80\%$的数据$n\leqslant 15$;
对于$100\%$的数据$n\leqslant 17$。
题解
看到数据范围是$17$的时候,我觉得这场考试我能$AK$;然而,当我看到是边集的时候,我发现半个小时之后机房里听不见一点键盘声……
同样,我们先考虑$60\%$的做法。
先给有向无环图分层,第一层是入度为$0$的点,第二层是删去第一层后度数为$0$的点,类似$topsort$?
然后设$dp[i][j]$表示当前选择的节点集合为$i$,最后一层的节点集合为$j$的方案数。
不妨设$s_1$表示当前选择的节点集合,$s_2$表示最后一层的节点的集合,$s_3$为$s_1$补集的子集,且$s_2$与$s_3$有连边,$s_1\oplus s_2$与$s_3$的连边为$cnt_1$条,$s_2$与$s_3$的连边有$cnt_2$条。
那么,状态转移方程为:
$$dp[s_1|s_3][s_3]=\sum dp[s_1][s_2]\times \prod 2^{cnt_1}\times (2^{cnt_2}-1)$$
这样的时间复杂度是$\Theta(4^n\times m)$的,无论空间还是时间都是不行的。
所以我们考虑减掉第二维,直接枚举当前选择的节点集合$s_1$,然后再枚举其补集的子集$s_2$,设$s_1$与$s_2$之间的连边有$cnt$条。
那么,你可能会列出这样一个状态转移方程:$dp[s_1|s_2]=dp[s_1]\times 2^{cnt}$。
但是你会发现答案会统计多,因为$s_1|s_2$可以由很多$s_1$和$s_2$组成,所以我们还需要容斥,其系数为$(-1)^{sz[s]+1}$。
这时候的时间复杂度为$\Theta(3^nm)$,只能拿到$80$分,还需要优化,有好多优化,我将其优化到了$\Theta(2^n\times n^2)$,这样就可以$AC$这道题了。
时间复杂度:$\Theta(2^n\times n^2)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int n,m;
bool Map[20][20];
int sz[131073];
int du[65537];
int sum[131073];
int qpow[1000];
int dp[131073];
int main()
{
scanf("%d%d",&n,&m);
int maxn=(1<<n);
dp[0]=qpow[0]=1;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
Map[x-1][y-1]=1;
qpow[i]=(qpow[i-1]<<1)%mod;
}
sz[0]=-1;
for(int i=1;i<maxn;i++)sz[i]=sz[i>>1]*(i&1?-1:1);
for(int i=0;i<maxn-1;i++)
{
if(!dp[i])continue;
int t=maxn-1-i;
memset(du,0,sizeof(du));
for(int j=0;j<n;j++)
if(i&(1<<j))
for(int k=0;k<n;k++)
du[1<<k]+=Map[j][k];
sum[0]=0;
for(int s=(t-1)&t;;s=(s-1)&t)
{
int now=t^s,lst=now&-now;
sum[now]=sum[now-lst]+du[lst];
dp[i+now]=(dp[i+now]+1LL*sz[now]*qpow[sum[now]]*dp[i])%mod;
if(!s)break;
}
}
printf("%lld",dp[maxn-1]);
return 0;
}
rp++
[CSP-S模拟测试]:巨神兵(状压DP)的更多相关文章
- NOIp模拟赛 巨神兵(状压DP 容斥)
\(Description\) 给定\(n\)个点\(m\)条边的有向图,求有多少个边集的子集,构成的图没有环. \(n\leq17\). \(Solution\) 问题也等价于,用不同的边集构造DA ...
- 2018.10.17 NOIP模拟 管道(状压dp)
传送门 状压dp好题. 怎么今天道道题都有点东西啊 对于今天题目神仙出题人先膜为上策:%%%%DzYoAk_UoI%%%% 设f[i][j]f[i][j]f[i][j]表示选取点的状态集合为iii,当 ...
- 2018.09.08 NOIP模拟 division(状压dp)
这么sb的题考场居然写挂了2233. 假设n=∏iaiki" role="presentation" style="position: relative;&qu ...
- 2018.08.29 NOIP模拟 movie(状压dp/随机化贪心)
[描述] 小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播 放.他希望连续看 L 分钟的电影.因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他 ...
- 4.26 省选模拟赛 T3 状压dp 差分求答案
LINK:T3 比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到. 一看到题求删除点的最少个 可以使得不连通. 瞬间想到最小割 发现对于10分直接跑最小割即可. 不过想 ...
- 【CSP模拟赛】Adore(状压dp 二进制)
题目描述 小w偶然间见到了一个DAG.这个DAG有m层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有k个节点.现在小w每次可以取反第i(1<i<n-1)层和第i+1层之间的连 ...
- [CSP-S模拟测试]:装饰(状压DP)
题目传送门(内部题114) 输入格式 第一行一个正整数$n$. 接下来一行$n-1$个正整数,第$i$个数为$f_{i+1}$. 接下来一行$n$个数,若第$i$个数为$0$则表示林先森希望$i$号点 ...
- 6.28 NOI模拟赛 好题 状压dp 随机化
算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...
- 【62测试】【状压dp】【dfs序】【线段树】
第一题: 给出一个长度不超过100只包含'B'和'R'的字符串,将其无限重复下去. 比如,BBRB则会形成 BBRBBBRBBBRB 现在给出一个区间[l,r]询问该区间内有多少个字符'B'(区间下标 ...
- 2018.10.05 NOIP模拟 上升序列(状压dp)
传送门 状压dp好题. 首先需要回忆O(nlogn)O(nlog n)O(nlogn)求lislislis的方法,我们会维护一个单调递增的ddd数组. 可以设计状态f(s1,s2)f(s1,s2)f( ...
随机推荐
- Linux 服务器安全优化
最小的权限+最少的服务=最大的安全 所以,无论是配置任何服务器,我们都必须把不用的服务关闭.把系统权限设置到最小,这样才能保证服务器最大的安全.下面是CentOS服务器安全设置,供大家参考. 一.注释 ...
- python正则表达式整理
正则表达式在处理字符串时很大的作用,爬虫中也经常用到,下面就将一些常用正则表达式做一整理记录,方便以后查看. ^d 表示匹配以d开头的字符串 . 表示匹配任意字符串 * 表示前面 ...
- oracle--序列&视图&索引&视图&可视化操作&分页&数据库备份
--oracle学习内容--oracle的管理系统学习--oracle的数据管理学习--oracle的用户管理--oracle二维表管理--oracle的其他知识 --oracle的序列.视图.索引 ...
- windows10安装ipython
Win10中如何装IPython?(其他Windows版本,如win7.win8/8.1也通用)我的这个方法比较简单,配置好环境变量敲几行命令就行了 .安装IPython的前提是已经安装好了Pytho ...
- 【洛谷p1190】接水问题
接水问题[题目链接] 咱也不知道为啥咱就是想写博客emmm 尽管这个题是2010年的普及组但是我太菜了并不会写emm 其实感觉这道题是纯纯正正的大模拟: 算法标签中的贪心是没有意义的啊?? SOLUT ...
- framebuffer设备驱动分析
一.设备驱动相关文件 1.1. 驱动框架相关文件 1.1.1. drivers/video/fbmem.c a. 创建graphics类.注册FB的字符设备驱动 fbmem_init(void) { ...
- 搜索(BFS)---计算在网格中从原点到特定点的最短路径长度
计算在网格中从原点到特定点的最短路径长度 [[1,1,0,1], [1,0,1,0], [1,1,1,1], [1,0,1,1]] 题目描述: 1表示可以经过某个地方,求解从(0,0)位置到(tr,t ...
- javascript中slice(),splice(),split(),substring(),substr()使用方法
因为本人在使用这些方法时常有混淆,特总结如下: 1.slice(): Array和String对象都有 在Array中 slice(i,[j]) i为开始截取的索引值,负数代表从末尾算起的索引值,- ...
- Route的exact属性
exact是Route下的一个属性,react路由会匹配到所有能匹配到的路由组件,exact能够使得路由的匹配更严格一些. exact的值为bool型,为true时表示严格匹配,为false时为正常匹 ...
- Docker备份镜像
docker save -o mycentos.tar mycentos_new:1.1 指定输出到的文件 执行后,运行 ls 命令即可看到打成的tar包, 因为有463M所以打包要一会