题解 \(by\;zj\varphi\)

首先发现一共最多只有 \(2^d\) 种道路,那么可以状压,(不要 \(dfs\),会搜索过多无用的状态)

那么设 \(f_{i,j,k}\) 为走 \(i\) 步,走到 \(j\),状态为 \(k\) 是否可行,那么转移就是 \(\mathcal O\rm (n^22^n)\),过不了

有一种技巧,叫 \(\rm meet\;in\;the\;middle\),从中间折半,设 \(f_{i,j,k}\) 表示由 \(1\) 出发,走 \(i\) 步到 \(j\),状态为 \(k\) 是否可行

\(g_{i,j,k}\) 表示以任意一个点为起点,其余同上

那么最终只要将两种状态拼起来即可,复杂度是 \(\mathcal O\rm (n^2*2^\frac{n}{2}+2^n)\)

注意,需要判断奇数折半的情况

Code
#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
template<typename T>inline void read(T &x) {
ri f=1;x=0;register char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
x=f?x:-x;
}
}
using IO::read;
namespace nanfeng{
#define pb(x) push_back(x)
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
static const int N=92;
bitset<1<<11> bit[12][N],bt[N];
bitset<2> eg[N][N];
int first[N],vis[1<<21],n,m,d,t=1,hd,ans;
struct edge{int v,nxt,c;}e[N*N<<1];
vector<int> sta[N],st2[N];
inline void add(int u,int v,int c) {
e[t].v=v,e[t].c=c,e[t].nxt=first[u],first[u]=t++;
e[t].v=u,e[t].c=c,e[t].nxt=first[v],first[v]=t++;
}
inline int main() {
// FI=freopen("nanfeng.in","r",stdin);
// FO=freopen("nanfeng.out","w",stdout);
read(n),read(m),read(d);
hd=d>>1;
for (ri i(1),u,v,c;i<=m;p(i)) {
read(u),read(v),read(c);
if (eg[u][v][c]) continue;
eg[u][v][c]=eg[v][u][c]=1;
add(u,v,c);
}
bit[0][1][0]=1;
for (ri i(0);i<hd;p(i)) {
int S=(1<<i)-1;
for (ri j(0);j<=S;p(j))
for (ri k(1);k<=n;p(k)) {
if (!bit[i][k][j]) continue;
for (ri ed(first[k]);ed;ed=e[ed].nxt) {
ri cst=j<<1|e[ed].c;
bit[i+1][e[ed].v][cst]=1;
if (i+1==hd&&!bt[e[ed].v][cst])
sta[e[ed].v].pb(cst),bt[e[ed].v][cst]=1;
}
}
}
for (ri i(0);i<=11;p(i))
for (ri j(0);j<N;p(j)) bit[i][j].reset();
for (ri i(1);i<=N;p(i)) bt[i].reset();
if (d&1) p(hd);
for (ri i(1);i<=n;p(i)) bit[0][i][0]=1;
for (ri i(0);i<hd;p(i)) {
int S=(1<<i)-1;
for (ri j(0);j<=S;p(j))
for (ri k(1);k<=n;p(k)) {
if (!bit[i][k][j]) continue;
for (ri ed(first[k]);ed;ed=e[ed].nxt) {
ri cst=j<<1|e[ed].c;
bit[i+1][e[ed].v][cst]=1;
if (i+1==hd&&!bt[e[ed].v][cst])
st2[e[ed].v].pb(cst),bt[e[ed].v][cst]=1;
}
}
}
for (ri i(1);i<=n;p(i)) {
ri siz=sta[i].size(),sz=st2[i].size();
for (ri j(0);j<siz;p(j)) {
ri tst=sta[i][j]<<hd;
for (ri k(0);k<sz;p(k)) {
ri stt=tst|st2[i][k];
if (!vis[stt]) p(ans),vis[stt]=1;
if (ans==(1<<d)) break;
}
if (ans==(1<<d)) break;
}
if (ans==(1<<d)) break;
}
printf("%d\n",ans);
return 0;
}
}
int main() {return nanfeng::main();}

NOIP 模拟 $20\; \rm y$的更多相关文章

  1. NOIP 模拟 $20\; \rm z$

    题解 很考验思维的一道题 对于不同的任务点,发现如果 \(x_{i-1}<x_i<x_{i+1}\) 或 \(x_{i-1}>x_i>x_{i+1}\) 那么 \(x_i\) ...

  2. NOIP 模拟 $20\; \rm 玩具$

    题解 \(by\;zj\varphi\) 一道概率与期望好题 对于一棵树,去掉根后所有子树就是一个森林,同理,一个森林加一个根就是一棵树 设 \(f_{i,j}\) 为有 \(i\) 个点的树,高度为 ...

  3. NOIP 模拟 $79\; \rm y$

    题解 \(by\;zj\varphi\) NOIP2013 的原题 最简单的思路就是一个 bfs,可以拿到 \(70pts\) 75pts #include<bits/stdc++.h> ...

  4. 7.22 NOIP模拟7

    又是炸掉的一次考试 T1.方程的解 本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判..暴力掉了40分. 首先a+b=c,只有一组解. 然后是a=1,b=1,答案是c-1 ...

  5. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  6. 20190725 NOIP模拟8

    今天起来就是虚的一批,然后7.15开始考试,整个前半个小时异常的困,然后一看题,T1一眼就看出了是KMP,但是完了,自己KMP的打法忘的一干二净,然后开始打T2,T2肝了一个tarjan点双就扔上去了 ...

  7. 20190902+0903合集-NOIP模拟

    一直没时间写QwQ 于是补一下. Day 1 晚饭吃的有点恶心…… $1s\,2s\,5s$ 还开 -O2 ?? 有点恐怖. T1 猛的一想: 把外面设成一个点, 向入口连一条权为排队时间的边 从出口 ...

  8. 2021.5.22 noip模拟1

    这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...

  9. NOIP 模拟 $16\; \rm Lost My Music$

    题解 \(by\;zj\varphi\) 一道凸包的题 设 \(\rm dep_u\) 表示节点 \(u\) 的深度,那么原式就可化为 \(-\frac{c_v-c_u}{dep_v-dep_u}\) ...

随机推荐

  1. GitHub 多人协作开发 三种方式(转)

    一.Fork 方式 网上介绍比较多的方式(比较大型的开源项目,比如cocos2d-x) 开发者 fork 自己生成一个独立的分支,跟主分支完全独立,pull代码后,项目维护者可根据代码质量决定是否me ...

  2. 「BZOJ2839」集合计数

    「BZOJ2839」集合计数 题目大意: 一个包含 \(n\) 个数的集合有 \(2^n\) 个子集,从这些子集中取出若干个集合(至少一个),使他们的交集的元素个数恰好为 \(k\),求方案数,答案对 ...

  3. 让我手把手教你写一个强大、方便使用的 IOC 容器

    一.介绍 1.介绍 最近无聊,也没什么事做,没事做总是要给自己找点事情做吧,毕竟人的生活在与折腾.于是,决定自己手动写一个 IOC 的框架.我们知道在 NetCore 的版本里面已经内置了 IOC 容 ...

  4. Activiti7 回退与会签

    1.  回退(驳回) 回退的思路就是动态更改节点的流向.先遇水搭桥,最后再过河拆桥. 具体操作如下: 取得当前节点的信息 取得当前节点的上一个节点的信息 保存当前节点的流向 新建流向,由当前节点指向上 ...

  5. MyBatis学习笔记(一):MAVEN的下载,安装与环境配置和在IDEA中配置maven

    一.下载 官网下载 :http://maven.apache.org/download.cgi 网速慢的也可以下载我配置好的国内阿里云仓库的.以下以我配置好的为例: 下载链接:https://pan. ...

  6. C语言变量为何先定义后使用

    C语言中,对变量的使用,首先要先定义.说明其数据类型.原因可能如下: 1不同类型的变量,其编码表示方式可能不同. 2不同类型的变量,其占有的空间大小不同.不事先说明无法在内存中开辟空间.

  7. jenkens离线安装插件方法,及插件下载地址

    1. 在可联网的计算机上登录jenkens,并安装需要的插件,安装的插件一般位于.../jenkens/plugins下. 2. 在/jenkens/plugins目录中拷贝已安装的插件到局域网下的j ...

  8. OpenSUSE Leap 42.1 KDE Ultmate Linux Distribution终极Linux系统试用与SSH连接

    系统安装环境: #一台旧笔记本电脑 #CPU Intel(R) Core(TM) i3 M 380 2.53GHz (4核) #内存 1G #硬盘存储 250G #系统型号 OpenSUSE Leap ...

  9. C#.NET 国密SM3withSM2签名与验签 和JAVA互通

    C# 基于.NET FRAMEWORK 4.5 JAVA 基于 JDK1.8 一.要点 1.签名算法:SM3withSM2. 2.签名值byte[] 转字符串时,双方要统一,这里是BASE64. 二. ...

  10. 构建前端第12篇之---在Vue中对组件,变量,函数的全局引入

    张燕涛写于2020-01-16 星期two 本篇还是源于import和export的使用,昨天看es6入门 和MDN文档,大体上用法了解了,但今天看ElementUI源码的时候,看到 //src/in ...