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. Redis Hashes 巧用sort排序

    假设我们有如下的数据结构: 我们想按download排序,并且返回hash中的其他field,需要怎么处理呢? 我们首先会想到sort命令.对,就是这个sort. 我们先看一下sort的语法: 可以看 ...

  2. Python之微信-微信机器人

    一 简介 二 登录微信 三 微信好友男女比例 四 微信好友地域分布 五 微信聊天机器人 一 简介 wxpy基于itchat,使用了 Web 微信的通讯协议,,通过大量接口优化提升了模块的易用性,并进行 ...

  3. phtyon,通过while循环简单的用户名和密码登录

    _username='zhangxin' _password='abc123' _username1='zhaopeng' _password1='abc1234' _username2=" ...

  4. java中"=="和equals方法究竟有什么区别?

    为什么会说到这个问题呢,是因为在java中遇到这个问题太常见了,无论是在写代码时还是在面试时.下面就一起探讨一下它们之间的联系与区别吧. 首先对于这样的问题,一般是先单独把一个东西说清楚,然后再说另一 ...

  5. 九度oj 题目1192:回文字符串

    题目1192:回文字符串 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4391 解决:2082 题目描述: 给出一个长度不超过1000的字符串,判断它是不是回文(顺读,逆读均相同)的. ...

  6. JavaEE JDBC RowSet行集

    RowSet行集 @author ixenos 应用背景 1.基于结果集的缺点:在与用户的整个交互过程中,必须始终与数据库保持连接 后果:当用户长时间离开时,数据库连接长时间被占用,而这属于稀缺资源: ...

  7. set/multiset用法详解

    集合 使用set或multiset之前,必须加入头文件<set> Set.multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素. sets和mul ...

  8. mongodb shell 无法删除问题

    1.MongoDB Shell中退格键使用的问题. 利用SecureCRT工具访问linux的时候,在使用MongoDB的交互式shell的时候,退格键(Backspace)无法使用,导致无 法修改输 ...

  9. [NOIP2004] 提高组 洛谷P1089 津津的储蓄计划

    题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同. 为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里 ...

  10. Codeforces908G. New Year and Original Order

    给n<=10^700,问1到n中每个数在各数位排序后得到的数的和.答案膜1e9+7. 一看就是数位DP啦..然而并没有什么思路.. 可以尝试统计n(i,j)表示数j在第i位的出现次数,知道了这个 ...