题目链接:

闲扯:

这题暴力分似乎挺多,但是一些奇奇怪怪的细节没注意RE了,还是太菜了

分析:

首先我们考虑最naiive的状压DP ,\(f[u][v][state]\)表示u开头,v结尾是否存在一条表示为state的路径,这个好转移不讲了,但是由于d的范围时间复杂度过大,于是考虑折半搜索

我们把一条最终路径的路径分成两部分\(p=(d+1)/2\)(其实就是上取整),\(q=d-p\),显然\(p>=q​\)

于是我们可以把一条路径长度看成两部分,一条从1开始,长度为p的路径,另一条以某点为开头,长度为q,终点恰好与第一条路径接上.

然后这时候我们就用\(ff[state][x]\)表示是否存在一条以x为开头,表示为state的路径,这个DP数组怎么得到呢?

我们枚举起点\(st\),再用一个数组\(f[state][x]\)表示是否存在一条st开头,x结尾,状态为state的路径,这个非常好转移我们从小到达枚举状态再根据两点之间是否连边转移

于是如果\(f[state]\)中存在一个值为1的元素,那么\(ff[state][st]=1\)

由于是折半路径,我们只需要将路径状态压为一个p位二进制数就好了

注意最后路径是从1开始,我们方便起见倒着枚举起点,最后枚举长度为p的前一半状态,和长度为q的后一半状态,如果存在一点v,\(ff[state_1][v]\)&\(f[state_2][v]==1\),那么方案数加1

同时预防前导0还需要特殊处理

还发现DP数组都是0/1序列,使用bitset减少操作时间复杂度

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <iostream>
#include <bitset>
#define ll long long
#define ri register int
using std::min;
using std::bitset;
using std::max;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int maxn=95;
const int inf=0x7fffffff;
const int N=1<<20-1;
bitset <maxn> g0[maxn],g1[maxn],f[N],ff[N];
int p,q;
inline void clear(){
for(ri i=0;i<N;i++)f[i].reset();
return ;
}
ll ans=0;
int n,m,d;
int main(){
int x,y,z;
#ifdef Luogu
freopen("y2.in","r",stdin);
freopen("y2.out","w",stdout);
#endif
read(n),read(m),read(d);
int p=(d+1)/2,q=d-p;
int o=1<<p,oo=1<<q;
for(ri i=1;i<=m;i++){
read(x),read(y),read(z);
if(z==1)g1[x][y]=g1[y][x]=1;
else g0[x][y]=g0[y][x]=1;
}
for(ri now=n;now>=1;now--){
clear();
f[1][now]=1;//避免前导0
for(ri i=1;i<o;i++){
for(ri j=1;j<=n;j++){
if(f[i][j]){//now循环中,f[state][v]表示now开头,v结尾状态为state的路径是否存在
f[i<<1]|=g0[j],f[i<<1|1]|=g1[j];
}
}
}//ff[state][u]表示从u开头,是否能走出一条状态为state的路径
for(ri i=0;i<o;i++)ff[i][now]=f[o|i].any();
}
for(ri i=0;i<o;i++){
for(ri j=0;j<oo;j++){
if((ff[i]&f[oo|j]).any())ans++;
}
//若存在点x f[state_1][x]=1并且ff[state_2][x]=1
//说明从x开头能走出一条state_2的路径
//从1开头,x结尾,又能走出一条state_1的路径,这样就能连起来成为一条合法的路径
}
printf("%lld\n",ans);
return 0;
}

[NOIP10.4模拟赛]2.y题解--折半搜索+状压计数的更多相关文章

  1. [NOIP10.6模拟赛]2.equation题解--DFS序+线段树

    题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...

  2. 20190716NOIP模拟赛T1 礼物(概率dp+状压)

    题目描述 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物. 商店里一共有种礼物.夏川每得到一种礼物,就会获得相应喜悦值Wi(每种 礼物的喜悦值不能重复获得). 每次,店员会 ...

  3. [NOIP10.4模拟赛]3.z题解--思维

    题目链接: 咕咕 闲扯: 哈哈这道T3考场上又敲了5个namespace,300+行,有了前车之鉴还对拍过,本以为子任务分稳了 结果只有30分哈哈,明明用极限数据对拍过不知怎么回事最后数据又是读不全, ...

  4. [NOIP10.3模拟赛]3.w题解--神奇树形DP

    题目链接: 咕 闲扯: 这题考场上把子任务都敲满了,5个namespace,400行11k 结果爆0了哈哈,因为写了个假快读只能读入一位数,所以手测数据都过了,交上去全TLE了 把边分成三类:0. 需 ...

  5. [NOIP10.5模拟赛]3.c题解--思维

    题目链接 这次不咕了 https://www.luogu.org/problemnew/show/AT2389 闲扯 考场20分爆搜走人 \cy 话说这几天T3都很考验思维啊 分析 我们先钦定一只鸡( ...

  6. [NOIP10.6模拟赛]1.merchant题解--思维+二分

    题目链接: while(1)gugu(while(1)) 闲扯 考场上怕T2正解写挂其他两题没管只打了暴力,晚上发现这题思维挺妙的 同时想吐槽出题人似乎热衷卡常...我的巨大常数现在显露无疑QAQ 分 ...

  7. [NOIP10.5模拟赛]1.a题解--离散化+异或线段树

    题目链接: 咕咕咕 https://www.luogu.org/problemnew/show/CF817F 闲扯 在Yali经历几天折磨后信心摧残,T1数据结构裸题考场上连暴力都TM没打满 分析 观 ...

  8. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  9. NOIP2017 宝藏 题解报告【状压dp】

    题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...

随机推荐

  1. PHP学习之观察者模式

    <?php //观察者模式涉及到两个类 //男人类 和女朋友类 //男人类对象小明, 女朋友类对象小花.小丽 class Man { //用了存放观察者 protected $observers ...

  2. python画图matplotlib基础笔记

    numpy~~基础计算库,多维数组处理 scipy~~基于numpy,用于数值计算等等,默认调用intel mkl(高度优化的数学库) pandas~~强大的数据框,基于numpy matplotli ...

  3. CentOS 7.4 发布下载,安全稳定的Linux发行版

    CentOS 7.4 发布了.CentOS 是 RHEL(Red Hat Enterprise Linux)源代码再编译的产物,而且在 RHEL 的基础上修正了不少已知的 Bug ,相对于其他 Lin ...

  4. 012-Spring Boot web【一】web项目搭建、请求参数、RestController、使用jsp、freemarker,web容器tomcat和jetty

    一.项目搭建 同:http://www.cnblogs.com/bjlhx/p/8324971.html 1)新建maven项目→使用默认配置即可 定义好项目名称等 2)修改jdk版本 <pro ...

  5. java使用jconsole查看java程序运行(jmx原理)

    在JVM启动参数上加上     java -Dcom.sun.management.jmxremote.port=8999     -Dcom.sun.management.jmxremote.aut ...

  6. vim基础学习1---简单命令

    1:vim abc:如果有abc文件,则打开,否则创建之后打开 2:输入"i",才可以输入东西 3:按Esc,它是底行模式,再敲":wq 回车" 保存退出. 4 ...

  7. Spring Aop(十三)——ProxyFactoryBean创建代理对象

    转发地址:https://www.iteye.com/blog/elim-2398673 ProxyFactoryBean创建代理对象 ProxyFactoryBean实现了Spring的Factor ...

  8. opengl读取灰度图生成三维地形

    准备第三方库 glew.freeglut.glm.opencv 准备灰度图片和草地贴图 最终效果 代码包括主程序源文件mainApp.cpp.顶点着色器shader.vs.片元着色器shader.fs ...

  9. Hadoop 3.1.3伪分布式环境安装Hive 3.1.2的异常总结

    背景:hadoop版本为3.1.3, 且以伪分布式形式安装,hive版本为3.1.2,hive为hadoop的一个客户端. 1. 安装简要步骤 (1) 官网下载apache-hive-3.1.2-bi ...

  10. 安卓运行linux应用程序

    安卓是可以运行linux应用程序的,安卓系统原来就基于Linux.但是安卓已经把linux改头换面了.具体方法是安装Termux软件,然后就可以运行pkg命令安装软件包了,希望可以帮助到大家.