题目来源:洛谷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. Java 异常的处理方式--throws和try catch

    异常的第一种处理方式throws. 看以下例子: import java.io.*;public class ExceptionTest04{ public static void main(Stri ...

  2. pom文件解析

    Maven的依赖是使用Maven坐标来定位的,而Maven坐标主要由GAV(groupId, artifactId, version)构成.因此,使用任何一个依赖之间,你都需要知道它的Maven坐标. ...

  3. 洛谷P2831 愤怒的小鸟(状压dp)

    题意 题目链接 Sol 这题....我样例没过就A了??..算了,就当是样例卡精度吧.. 直接状压dp一下,\(f[sta]\)表示干掉\(sta\)这个集合里面的鸟的最小操作数 转移的时候判断一下一 ...

  4. framework7的改进,以及与vue组合使用遇到的问题以及解决方法 (附vue的原理)

    framework7官方提供了vue+framework7的组合包,但是那个包用起来复杂度较高,而且不灵活.听说bug也不少. 所以我想用最原始的方式单独使用vue和framework7. 遇到以下问 ...

  5. ActiveX界面已显示,调用方法报undefined的处理办法

    1.在ie中将当前网址加入信任网站 2.设置->internet选项->安全->受信任站点->自定义级别:将所有有关ActiveX的选项设置为启用 3.重启ie再次访问即可. ...

  6. CentOS 7运维管理笔记(2)----修改命令提示符颜色

    使用 su  命令切换到root用户: 使用 vi /etc/bashrc 命令插入如下代码: PS1="[\e[1;32m\u\e[m\e[1;33m@\e[m\e[1;35m\h\e[m ...

  7. ArcGIS中国工具(ArcGISCTools)2.0正式发布

    ArcGIS中国工具,简称CTools,集成在ArcMap10.0, ArcMap10.1, ArcMap10.2,安装就可以直接使用.主要有以下功能 1.接合图表生成2.图框工具3.制图工具4.图形 ...

  8. vs2010开发activex(MFC)控件/ie插件(一)

    原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/50782904  vs2010开发activex(MFC)控件:      第一步:生成ac ...

  9. 【Markdown】Markdown 使用MathJax引擎 书写Latex 数学公式

    大家都看过Stackoverflow上的公式吧,漂亮,其生成的不是图片.这就要用到MathJax引擎,在Markdown中添加MathJax引擎也很简单, <script type=" ...

  10. 20.远程分支&跟踪分支

    远程分支 远程引用是对远程仓库的引用(指针),包括分支.标签等等. 你可以通过 git ls-remote (remote) 来显式地获得远程引用的完整列表,或者通过 git remote show ...