noip2017 D1T3 逛公园 某zz选手看到数据范围直接就最短路计数了,结果写错了爆零

题目大意:

N个点M条边构成的有向图,且没有自环和重边。其中1号点是起点,N号点是公园的终点,每条边有一个非负权值, 代表经过这条边所要花的时间

如果1号点到N号点的最短路长为d,那么策策只选择长度不超过d + K的路线

求总共有多少条满足条件的路线

为避免输出过大,答案对P取模。

如果有无穷多条合法的路线,请输出−1

思路:

首先需要求出最短路用spfa

然后我们dfs的时候dp

具体见注释

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 2139062143
#define ll long long
#define MAXN 100100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int T,n,m,k,MOD;
int cnt,nxt[MAXN*],fst[MAXN],to[MAXN*],val[MAXN*];
int Cnt,Nxt[MAXN*],Fst[MAXN],To[MAXN*],Val[MAXN*];
int dis[MAXN],dp[MAXN][];
bool vis[MAXN],jdg[MAXN][],f;
void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
void Add(int u,int v,int w) {Nxt[++Cnt]=Fst[u],Fst[u]=Cnt,To[Cnt]=v,Val[Cnt]=w;}
void spfa()
{
memset(dis,,sizeof(dis));
queue <int> q;
dis[]=,vis[]=;q.push();
while(!q.empty())
{
int k=q.front();
q.pop();vis[k]=;
for(int i=fst[k];i;i=nxt[i])
if(dis[k]+val[i]<dis[to[i]]) {dis[to[i]]=dis[k]+val[i];if(!vis[to[i]]){vis[to[i]]=;q.push(to[i]);}}
}
}
int dfs(int x,int ext)//表示走到x节点刚好多走了ext dfs的时候按照反向边走
{
if(dp[x][ext]!=-) return dp[x][ext];
jdg[x][ext]=,dp[x][ext]=;//jdg用来判零环 (如果一个点相同的ext在dp还未被确定的情况下被访问了两遍,说明有零环)
for(int i=Fst[x];i;i=Nxt[i])
{
if(dis[x]-dis[To[i]]+ext-Val[i]<) continue;//这么长的一大串表示按这条边走的ext <0说明不能按这条边走
if(jdg[To[i]][dis[x]-dis[To[i]]+ext-Val[i]]) f=;//有零环
(dp[x][ext]+=dfs(To[i],dis[x]-dis[To[i]]+ext-Val[i]))%=MOD;//接着dfs
}
jdg[x][ext]=;
return dp[x][ext];
}
int main()
{
T=read();
int a,b,c,ans=;
while(T--)
{
memset(nxt,,sizeof(nxt));
memset(Nxt,,sizeof(Nxt));
memset(Fst,,sizeof(Fst));
memset(fst,,sizeof(fst));
memset(jdg,,sizeof(jdg));
memset(vis,,sizeof(vis));
memset(dp,0xff,sizeof(dp));//设为-1是因为在这个dp里 0也是一种合法的结果
n=read(),m=read(),k=read(),MOD=read(),cnt=Cnt=;
for(int i=;i<=m;i++) {a=read(),b=read(),c=read();add(a,b,c);Add(b,a,c);}
spfa();//处理出最短路
ans=f=,dp[][]=;
for(int i=;i<=k;i++) (ans+=dfs(n,i))%=MOD;//倒着dfs 在搜索的过程中能够非常巧妙地判断零环
dfs(n,k+);//用来判断k==0时有零环的情况
if(f) puts("-1");
else printf("%d\n",ans);
}
}

luogu 3953 逛公园的更多相关文章

  1. [Luogu P3953] 逛公园 (最短路+拓扑排序+DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易 ...

  2. Luogu P3953 逛公园(最短路+记忆化搜索)

    P3953 逛公园 题面 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园的入口,\(N\) 号点是公 ...

  3. 【luogu P3953 逛公园】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3953 题外话:感觉2017年神题好多..这还不是最神的一道,真在考场上我也就写个最短路计数暴力了.现在在大佬 ...

  4. Luogu P3953 逛公园

    不管怎么说,这都是一道十分神仙的NOIp题 你可以说它狗,但不可以否认它就是NOIp的难度 首先这道题很显然是道图论题还是一道图论三合一(最短路+拓扑+图上DP) 先考虑最短路,我们分别以\(1\)和 ...

  5. [luogu P3953] [noip2017 d1t3] 逛公园

    [luogu P3953] [noip2017 d1t3] 逛公园 题目描述 策策同学特别喜欢逛公园.公园可以看成一张$N$个点$M$条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,$N ...

  6. 【洛谷】3953:逛公园【反向最短路】【记忆化搜索(DP)统计方案】

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

  7. 【图论 动态规划拆点】luoguP3953 逛公园

    经典的动态规划拆点问题. 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 NN 个点 MM 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, NN 号点是公园的出口,每条边有一个非负 ...

  8. [vijos P1083] 小白逛公园

    不知怎地竟有种错觉此题最近做过= =目测是类似的?那道题貌似是纯动归? 本来今晚想做两道题的,一道是本题,一道是P1653疯狂的方格取数或NOI08 Employee,看看现在的时间目测这个目标又达不 ...

  9. Bzoj 1756: Vijos1083 小白逛公园 线段树

    1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1021  Solved: 326[Submit][Statu ...

随机推荐

  1. 测试Mysql悲观锁

  2. 配置Django+mysql+pydev(x64)

    mysqldb需要安装64位的(http://ishare.iask.sina.com.cn/f/21839771.html),否则出现 import _mysql ImportError: DLL ...

  3. 竞赛Noi_Linux使用总结(vim)

    刚换完Linux,趁着教练给的改题时间(T2确实猛)自己上网找了好多博客,发现很多跟竞赛有关的内容是碎片化的,从最基本的如何用vim写代码.编译.运行,再到怎么改设置使打代码时手感强一些,最后学对拍, ...

  4. ROS 笔记 程序包/节点/topic

    官方教程: wiki.ros.org/cn/ROS/tutorials 程序包打创建于编译 创建程序包 在工作空间的src底下,输入如下命令: $ catkin_create_pkg 要创建的包名 依 ...

  5. 怎样判断有没有SQL注入?

    最为经典的单引号判断法: 在参数后面加上单引号,比如: http://xxx/abc.php?id=1' 如果页面返回错误,则存在 Sql 注入. 原因是无论字符型还是整型都会因为单引号个数不匹配而报 ...

  6. Ubuntu中Hadoop环境搭建

    Ubuntu中Hadoop环境搭建 JDK安装 方法一:通过命令行直接安装(不建议) 有两种java可以安装oracle-java8-installer以及openjdk (1)安装oracle-ja ...

  7. HDU-1597find the nth digit,超短代码一遍过,啦啦啦啦~~

    find the nth digit                                                                    Time Limit: 10 ...

  8. hihoCoder#1114 小Hi小Ho的惊天大作战:扫雷·一

    原题地址 回溯+搜索 枚举每个位置上能否放地雷,当第i个位置枚举完成后,第i-1个位置的情况就确定了,此时,检查第i-1个位置是否满足要求,即左右间隔为1的范围内地雷数是否等于申明数字,如果满足条件, ...

  9. hdu - 1254 推箱子 (bfs+bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目意思很简单,只要思路对就好. 首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工 ...

  10. 洛谷 P1122 最大子树和

    P1122 最大子树和 题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的 ...