题目来源:洛谷P3953

思路

先用SPFA求一遍最短路

在求最短路的同时可以把所有点到终点的最短路求出来 dis数组

注意要反向SPFA  因为从起点开始可能会走到一些奇怪的路上导致时间负责度增加

我们定一个f[u][k]数组为从当前节点u还剩时间k到达终点的方案

原来从u走到终点的最短路径消耗时间为dis[u]

而我们现在考虑走(u,v,w)这条边(不是最短路)

那么比走最短路需要多dis[v]+w-dis[u]的时间

所以f[u][k]=∑f[v][k-(dis[v]+w-dis[u])] (从u到终点上有另一个点v)

记忆化搜索即可

PS:容易错的地方是没有初始化

代码

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 100010
#define INF 1e9+7
int T,n,m,k,p,cnt,limit,ans;
int dis[maxn],h1[maxn],h2[maxn],f[maxn][];
bool vis[maxn],v[maxn][];
struct Edge
{
int to;
int next;
int w;
}e1[maxn*],e2[maxn*];
void add(int u,int v,int w)
{
e1[++cnt].to=v;
e1[cnt].w=w;
e1[cnt].next=h1[u];
h1[u]=cnt;
e2[cnt].to=u;
e2[cnt].w=w;
e2[cnt].next=h2[v];
h2[v]=cnt;
}
void spfa()//反向SPFA
{
queue<int> q;
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++) dis[i]=INF;
q.push(n);
dis[n]=;
vis[n]=;
while(!q.empty())
{
int temp=q.front();
q.pop();
vis[temp]=;
for(int i=h2[temp];i;i=e2[i].next)
{
int v=e2[i].to;
if(dis[v]>dis[temp]+e2[i].w)
{
dis[v]=dis[temp]+e2[i].w;
if(!vis[v])
{
vis[v]=;
q.push(v);
}
}
}
}
}
int dfs(int u,int k)
{
if(v[u][k]) return -;//如果一条路上一个点第二次到达 说明有环
if(f[u][k]) return f[u][k];//记忆化
v[u][k]=;
if(u==n) f[u][k]=;//边界条件 到达终点还剩k步方案数为1
else f[u][k]=;//否则为0
for(int i=h1[u];i;i=e1[i].next)
{
int v=e1[i].to;
int temp=dis[v]-dis[u]+e1[i].w;//判断每一条路相比最短路是否超过k
if(temp<=k)//没超过
{
int w=dfs(v,k-temp);//继续dfs 记得减去剩余时间
if(w==-) return f[u][k]=-;
f[u][k]=(f[u][k]+w)%p;//记录方案数
}
}
v[u][k]=;//重置点
return f[u][k];
}
int main()
{
cin>>T;
while(T--)
{
cnt=,ans=;
memset(h1,,sizeof(h1));//记得初始化
memset(h2,,sizeof(h2));
memset(f,,sizeof(f));
memset(v,,sizeof(v));
cin>>n>>m>>k>>p;
for(int i=;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
}
spfa();
cout<<dfs(,k)<<endl;//ans在dfs(1,k)中
}
}

【题解】洛谷P3953 [NOIP2017TG] 逛公园(记忆化搜索+SPFA)的更多相关文章

  1. 洛谷3953 (NOIp2017) 逛公园——记忆化搜索+用栈判0环

    题目:https://www.luogu.org/problemnew/show/P3953 因为K只有50,所以想到用dp[ cr ][ j ]表示在点cr.比最短路多走了 j 的方案数.(看了TJ ...

  2. NOIP 2017 逛公园 记忆化搜索 最短路 好题

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

  3. 洛谷P1192 台阶问题【记忆化搜索】

    题目:https://www.luogu.org/problemnew/show/P1192 题意: 给定n和k,一个人一次可以迈1~k步,问走n步有多少种方案. 思路: 本来傻乎乎上来就递归,显然会 ...

  4. 洛谷P1040 加分二叉树【记忆化搜索】

    题目链接:https://www.luogu.org/problemnew/show/P1040 题意: 某一个二叉树的中序遍历是1~n,每个节点有一个分数(正整数). 二叉树的分数是左子树分数乘右子 ...

  5. 洛谷P3953 [NOIP2017]逛公园

    K<=50,感觉可以DP 先建反图求出从n到各个点的最短路,然后在正图上DP 设f[当前点][比最短路多走的距离]=方案数 转移显然是 $f[v][res]=\sum f[u][res+tmp] ...

  6. 洛谷 P1141【BFS】+记忆化搜索+染色

    题目链接:https://www.luogu.org/problemnew/show/P1141 题目描述 有一个仅由数字 0 与 1 组成的n×n 格迷宫.若你位于一格0上,那么你可以移动到相邻 4 ...

  7. 洛谷P3906 Hoof Paper, Scissor (记忆化搜索)

    这道题问的是石头剪刀布的的出题问题 首先不难看出这是个dp题 其次这道题的状态也很好确定,之前输赢与之后无关,确定三个状态:当前位置,当前手势,当前剩余次数,所以对于剪刀,要么出石头+1分用一次机会, ...

  8. 【洛谷1434 [SHOI2002]滑雪】记忆化搜索

    AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...

  9. 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)

    P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...

随机推荐

  1. 卸载或安装程序出现:The feature you are trying to use is on a network resource ...

    卸载或安装程序出现:The feature you are trying to use is on a network resource ... 这种情况可能是因为原先已经安装过这个软件,所以要先卸载 ...

  2. css之子元素获取(未定义高度)父元素的高度

    你可能碰到过这样的需求,一个高度不固定的区域(内容由用户创造),当鼠标经过该区域或者其神马操作时,需要出现一个与该区域一样大的模版: 我们用一个span来处理这个mask.由于 .sample-1 和 ...

  3. IOC和DI到底是什么?

     在学习Spring框架的时候,我们总是能见到IOC这个单词,也时常听到DI这个词,那么他们分别是什么意思呢?接下来就讲讲个人对于这两个概念的理解  一.IOC和DI概念 IOC(控制反转):全称为: ...

  4. 爬虫之Beautifulsoup的基本实用

    基本方法如下: # soup.a 只能找到第一个符合要求的标签 # soup.a.attrs 获取a所有的属性和属性值 # soup.a.attrs['href'] 获取href属性 # soup.a ...

  5. js对象之间的继承

    js的对象之间的继承抛弃了原型与构造器的概念,而转为字面量对象之间进行属性拷贝的方式进行继承. 首先我们来写一个封装好的继承函数: function extend(parent){ var child ...

  6. C# 索引器的使用

    索引器允许类或者结构的实例按照与数组相同的方式进行索引取值,索引器与属性类似,不同的是索引器的访问是带参的. 索引器和数组比较: (1)索引器的索引值(Index)类型不受限制 (2)索引器允许重载 ...

  7. 理解LSTM/RNN中的Attention机制

    转自:http://www.jeyzhang.com/understand-attention-in-rnn.html,感谢分享! 导读 目前采用编码器-解码器 (Encode-Decode) 结构的 ...

  8. SQL点点滴滴_聚集索引设计指南-转载

    聚集索引基于数据行的键值在表内排序和存储这些数据行, 每个表只能有一个聚集索引, 因为数据行本身只能按一个顺序存储. 有关聚集索引体系结构的详细信息, 请参阅 聚集索引结构. 每个表几乎都对列定义聚集 ...

  9. sql server 获取表结构和记录数

    表结构 then d.name else null end) 表名, a.colorder 字段序号,a.name 字段名, ( then '√'else '' end) 标识, (case when ...

  10. docker commit 显示“invalid reference format”

    docker commit的时候一直显示invalid reference format,改了几次也不行,后来发现是因为docker镜像的名字中不能包含大写字母,改成小写后就行了