记忆化搜索

跑一次反向的最短路求出MinDis(u,n)MinDis(u,n)MinDis(u,n)

f[u][k]f[u][k]f[u][k]表示dis(u,n)&lt;=MinDis(u,n)+dis(u,n)&lt;=MinDis(u,n)+kdis(u,n)&lt;=MinDis(u,n)+dis(u,n)&lt;=MinDis(u,n)+kdis(u,n)<=MinDis(u,n)+dis(u,n)<=MinDis(u,n)+k的方案数,答案就是f[1][K]f[1][K]f[1][K]

考虑egde(u,v,w)egde(u,v,w)egde(u,v,w)

同样的道理走这条边的话, dis(v,n)=MinDis(v,n)+w−MinDis(u,n)dis(v,n)=MinDis(v,n)+w-MinDis(u,n)dis(v,n)=MinDis(v,n)+w−MinDis(u,n)

f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]f[u][k]=∑f[v][k-(MinDis(v,n)-MinDis(u,n)+w)]f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]

⇒f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]

这样怎么判000环呢?只要在搜索的时候记录个instackinstackinstack就okokok了

如果当前的转状态还在搜索的栈中就可以直接返回−1-1−1了

AC code:

#include<bits/stdc++.h>
using namespace std; inline void read(int &num)
{
char ch; int flag=1;
while(!isdigit(ch=getchar()))if(ch=='-')flag=-flag;
for(num=ch-'0';isdigit(ch=getchar());num=num*10+ch-'0');
num*=flag;
} const int MAXN = 100005;
const int MAXM = 200005;
const int MAXK = 55; int n, m, k, p, f[MAXN][MAXK];
bool instk[MAXN][MAXK]; int fir[MAXN], to[MAXM], nxt[MAXM], wt[MAXM], cnt;
int rfir[MAXN], rto[MAXM], rnxt[MAXM], rwt[MAXM], rcnt; inline void Add(int u, int v, int w) { to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; wt[cnt] = w; }
inline void rAdd(int u, int v, int w) { rto[++rcnt] = v; rnxt[rcnt] = rfir[u]; rfir[u] = rcnt; rwt[rcnt] = w; } int dis[MAXN];
bool inq[MAXN];
queue<int>Q;
void spfa(int T)
{
memset(dis, 0x7f, sizeof dis);
dis[T] = 0; inq[T] = 1; Q.push(T);
while(!Q.empty())
{
int u = Q.front(); inq[u] = 0; Q.pop();
for(int i = rfir[u]; i; i = rnxt[i])
if(dis[rto[i]] > dis[u] + rwt[i])
{
dis[rto[i]] = dis[u] + rwt[i];
if(!inq[rto[i]])
inq[rto[i]] = 1, Q.push(rto[i]);
}
}
} int dfs(int u, int now)
{
if(instk[u][now]) return -1;
if(f[u][now]) return f[u][now];
instk[u][now] = 1;
if(u == n) f[u][now] = 1;
for(int i = fir[u], tmp; i; i = nxt[i])
if(dis[to[i]]-dis[u]+wt[i] <= now)
{
if((tmp=dfs(to[i], now-dis[to[i]]+dis[u]-wt[i])) == -1) return f[u][now] = -1;
(f[u][now] += tmp) %= p;
}
return instk[u][now] = 0, f[u][now];
} int main ()
{
int T, x, y, z;
read(T);
while(T--)
{
memset(f, 0, sizeof f);
memset(instk, 0, sizeof instk);
memset(fir, 0, sizeof fir); cnt = 0;
memset(rfir, 0, sizeof fir); rcnt = 0;
read(n), read(m), read(k), read(p);
for(int i = 1; i <= m; i++)
{
read(x), read(y), read(z);
Add(x, y, z), rAdd(y, x, z);
}
spfa(n);
printf("%d\n", dfs(1, k));
}
}

【NOIP2017】逛公园 D1 T3的更多相关文章

  1. 【题解】NOIP2017逛公园(DP)

    [题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n​节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...

  2. [NOIP2017] 逛公园

    [NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^ ...

  3. 【比赛】NOIP2017 逛公园

    考试的时候灵光一闪,瞬间推出DP方程,但是不知道怎么判-1,然后?然后就炸了. 后来发现,我只要把拓扑和DP分开,中间加一个判断,就AC了,可惜. 看这道题,我们首先来想有哪些情况是-1:只要有零环在 ...

  4. NOIP2017逛公园(dp+最短路)

    策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会 ...

  5. NOIP2017 逛公园 题解报告 【最短路 + 拓扑序 + dp】

    题目描述 策策同学特别喜欢逛公园.公园可以看成一张NNN个点MMM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,NNN号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花 ...

  6. [NOIP2017]逛公园 题解

    我连D1T3都不会我联赛完蛋了 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 N 个点 M 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, N 号点是公园的出口,每条边有一个非负 ...

  7. [NOIP2017] 逛公园 解题报告(DP)

    我很不想说 在我的AC代码上我打了表,但实在没有办法了.莫名的8,9个点RE.然而即便是打表...也花了我很久. 这大概是NOIP2017最难的题了,为了让不懂的人更容易理解,这篇题解会比较详细 我的 ...

  8. Luogu P3953 [NOIP2017]逛公园

    题目 首先我们跑出从\(1\)出发的最短路\(d1\)和反图上从\(n\)出发的最短路\(dn\). 然后我们处理出长度不超过\(d1_n+k\)的最短路边集,给它拓扑排序. 如果存在环,那么这个环一 ...

  9. [NOIP2017] 逛公园 【最短路】【强连通分量】

    题目分析: 首先考虑无数条的情况.出现这种情况一定是一条合法路径经过了$ 0 $环中的点.那么预先判出$ 0 $环中的点和其与$ 1 $和$ n $的距离.加起来若离最短路径不超过$ k $则输出$ ...

随机推荐

  1. Python之路【第三十一篇】:django ajax

    Ajax 文件夹为Ajaxdemo 向服务器发送请求的途径: 1.浏览器地址栏,默认get请求: 2.form表单: get请求 post请求 3.a标签,超链接(get请求) 4.Ajax请求 特点 ...

  2. Partition5:Partiton Scheme是否指定Next Used?

    在SQL Server中,为Partition Scheme多次指定Next Used,不会出错,最后一次指定的FileGroup是Partition Scheme的Next Used,建议,在执行P ...

  3. webpack集成vue单文件模式的很多坑(研究了1个星期)

    1.一开始不知道局部安装webpack后,如何调用webpack. 后来看说明文档(webpack中文网)才知道,有个npx可以启动本地安装的webpack. 我估计:全局安装webpack,全局的w ...

  4. 关于justify-content属性的再学习(区分三个属性)

    justify-content属性: 用来表示可伸缩项目在主轴方向上的对齐方式: 取值范围为flex-start,flex-end,center,space-between,space-around: ...

  5. honeydctl命令

    # honeydctl Honeyd 1.5c Management Console Copyright (c) 2004 Niels Provos. All rights reserved. See ...

  6. css 三角形空心三角形的简单实现

    <style> #talkbubble { width: 120px; height: 80px; position: relative; -moz-border-radius: 10px ...

  7. 手动实现KNN算法

    手动实现KNN算法 计算距离 取k个邻近排序 距离(欧氏) 预习 import numpy as np # 数组运算是面向元素级别的 arr1 = np.array([1,2,3]) arr2 = n ...

  8. C#-使用GoogleAPI读写spreadsheets

    https://docs.google.com/spreadsheets/在线使用一些常用办公工具,比如excel. 如需要C#代码自动读写这些excel,则需要使用GoogleAPI. 封装的公用类 ...

  9. xadmin集成DjangoUeditor,以及编辑器的视频路径配置

    稍微讲一下DjangoUeditor的配置,因为之前去找配置的时候东拼西凑的,所以自己写一下自己一步步配置的过程.首先我是再github上去下载下来,因为是当作第三方插件集成到xadmin中,所以不用 ...

  10. Sleep和 SleepEx函数

    Sleep和 SleepEx函数的功能是在指定的执行时间内中止所在线程的执行. SleepEx扩展了Sleep的功能,在最短超时时间间隔已到的情况下恢复线程执行外,在以下两种情况下发生时也可以恢复执行 ...