问题描述

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

策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间。如果1号点 到 N 号点的最短路长为 d ,那么策策只会喜欢长度不超过d+K 的路线。
策策同学想知道总共有多少条满足条件的路线,你能帮帮它吗?
为避免输出过大,答案对 P 取模。
如果有无穷多条合法的路线,请输出 -1 。
输入格式
第一行包含一个整数 T , 代表数据组数。
接下来 TT 组数据,对于每组数据: 第一行包含四个整数 N,M,K,P ,每两个整数之间用一个空格隔开。
接下来 M 行,每行三个整数 ai,bi,ciai,bi,cia_i,b_i,c_i,代表编号为ai,biai,bi a_i,b_i的点之间有一条权值为ci的有向边,每两个整数之间用一个空格隔开。
输出格式
输出文件包含 T 行,每行一个整数代表答案。
样例输入

4
1 2 1
1 3 2
3 4 3
2
2 2

样例输出

3
-1

思路分析

只要跑一次反向的最短路
f[u][k] 表示 dis(u,n)<=MinDis(u,n)+k 的方案数,答案就是f[1][K]
考虑 egde(u,v,w)
同样的道理走这条边的话,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)]\Rightarrow 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)]
这样怎么判 0 环呢?只要在搜索的时候记录个 instack 就 ok 了
如果当前的 vv 还在搜索的栈中就可以直接返回 -1 了

AC代码

#include<cstdio>
#include<cstring>
#define re register int
#define fp(i,a,b) for(re i=a,I=b;i<=I;++i)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
char ss[1<<17],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<17,stdin),A==B)?-1:*A++;}
template<class T>inline void sdf(T&x){char c;T y=1;while(c=gc(),(c<48||57<c)&&c!=-1)if(c=='-')y=-1;x=c^48;while(c=gc(),47<c&&c<58)x=(x<<1)+(x<<3)+(c^48);x*=y;
}
const int N=1e5+5,M=2e5+5;
typedef int arr[N];
struct eg{int nx,to,w;}e[M<<1];
int T,n,m,K,P,ce,f[N][51];arr dis,f1,fn;bool in[N][51];
namespace seg{int tr[N<<2],sgt;inline void Set(re n){sgt=1;while(sgt<=n)sgt<<=1;--sgt;tr[0]=N-1;}inline void clr(){fp(i,1,(sgt<<1)+1)tr[i]=0;}inline int cmp(const re&a,const re&b){return dis[a]<dis[b]?a:b;}inline void mdy(re x,re w){for(re i=x+sgt;dis[tr[i]]>w;i>>=1)tr[i]=x;dis[x]=w;}inline void del(re x){tr[x+=sgt]=0;x>>=1;while(x)tr[x]=cmp(tr[x<<1],tr[x<<1|1]),x>>=1;}
}
using namespace seg;
void dij(){memset(dis,9,4*(n+1));clr();mdy(n,0);fp(T,1,n){re u=tr[1];del(u);for(re i=fn[u],v;i;i=e[i].nx)if(dis[v=e[i].to]>dis[u]+e[i].w)mdy(v,dis[u]+e[i].w);}
}
inline void add(re u,re v,re w,re*fi){e[++ce]=(eg){fi[u],v,w};fi[u]=ce;}
inline void mod(re&a){a>=P?a-=P:0;}
int dfs(re u,re k){if(in[u][k])return -1;if(f[u][k])return f[u][k];in[u][k]=1;u==n?f[u][k]=1:0;for(re i=f1[u],v,w,tp;i;i=e[i].nx)if((tp=dis[v=e[i].to]-dis[u]+e[i].w)<=k){if((w=dfs(v,k-tp))==-1)return f[u][k]=-1;mod(f[u][k]+=w);}return in[u][k]=0,f[u][k];
}
int main(){#ifndef ONLINE_JUDGEfile("park");#endifsdf(T);while(T--){memset(f,0,sizeof f);memset(in,0,sizeof in);sdf(n);sdf(m);sdf(K);sdf(P);Set(n);re u,v,w;memset(f1,ce=0,4*(n+1));memset(fn,0,4*(n+1));while(m--)sdf(u),sdf(v),sdf(w),add(u,v,w,f1),add(v,u,w,fn);dij();printf("%d\n",dfs(1,K));}
return 0;
}

NOIP2017D1T3-逛公园相关推荐

  1. TYVJ1427 小白逛公园

    P1427 小白逛公园 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦-在小新家附近有一条"公园路&qu ...

  2. JZOJ 5475. 【NOIP2017提高组正式赛】逛公园

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

  3. 牛客小白月赛12 I 华华和月月逛公园 (tarjian 求桥)

    链接:https://ac.nowcoder.com/acm/contest/392/I 来源:牛客网 华华和月月逛公园 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K, ...

  4. 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索

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

  5. 【ybt高效进阶4-4-3】【luogu P4513】公园遛狗 / 小白逛公园

    公园遛狗 / 小白逛公园 题目链接:ybt高效进阶4-4-3 / luogu P4513 题目大意 给你一个序列,要维护两个操作. 单点修改和在一个区间中找权值最大的子区间的权值. 思路 其实这个是很 ...

  6. 公园遛狗(小 * 逛公园)

    P4513 小白逛公园 线段树求最大子段和,由于是动态的且n,m均高达1e5,因此想到线段树 #include<bits/stdc++.h> using namespace std; #d ...

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

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

  8. 牛客网IT校招编程题-逛公园-Python

    题目描述: 又是晴朗的一天,牛牛的小伙伴们都跑来找牛牛去公园玩.但是牛牛想呆在家里看E3展,不想出去逛公园,可是牛牛又不想鸽掉他的小伙伴们,于是找来了公园的地图,发现公园是由一个边长为n的正方形构成的 ...

  9. 洛谷 P3953 [NOIP2017 提高组] 逛公园

    开始刷题单啦~,这部分的洛谷好题作为个人训练记录和以后复习用,有兴趣的可以一起做做 题目链接:P3953 [NOIP2017 提高组] 逛公园 题意都是中文就不翻译了 题解:这是一道记忆化+搜索的题目 ...

  10. 【NOIP 2017 提高组】逛公园

    [题目] 传送门 题目描述: 策策同学特别喜欢逛公园.公园可以看成一张 nnn 个点 mmm 条边构成的有向图,且没有自环和重边.其中 111 号点是公园的入口,nnn 号点是公园的出口,每条边有一个 ...

最新文章

  1. 研究速递:预测学习——神经元高效运作的最佳策略
  2. java.net.SocketException四大异常解决方案
  3. 给 Javascript 加上面向对象的属性:Class.js
  4. 表达式计算器类的设计4(面向对象的表达式计算器7)
  5. nginx开发笔记_ngx_hash源码解析
  6. ~~分解质因数法求组合数
  7. 不会编程没关系,有了这个“Excel”,零基础上手生成网络
  8. 《Entity Framework 6 Recipes》中文翻译系列 (11) -----第三章 查询之异步查询 (转)...
  9. 车载网络技术革新-CAN FD浅析
  10. wget下载nessus
  11. mysql数据库更新数据库语句_MySQL数据库之UPDATE更新语句精解
  12. 51单片机 矩阵键盘
  13. python地理数据处理 下载_Python批量下载地理空间数据云数据!Python无所不能!...
  14. Gmail大改版,36岁的电子邮箱为何未像BBS一样消亡?
  15. mysql 根据英文首字母来查询汉字
  16. 有若干只鸡兔同在一个笼子里,从上面数,有35个头;从下面数,有94只脚。求笼中各有几只鸡和兔?
  17. 求1-1/2+1/3-1/4+……+1/99-1/100 的值
  18. solaris系统关闭服务器,Solaris下如何关闭SUN服务器
  19. C语言编程学习:使用函数必须知道的3点注意事项
  20. [胡搞]Deecamp 2019 第二次考试B卷笔试知识点回忆

热门文章

  1. C语言数组之间赋值详解
  2. Redis学习Python3.6实现备忘录
  3. 公众号菜单添加外部链接
  4. python官网下载速度过慢
  5. Spring Cloud Gateway高危漏洞修复方案
  6. python求直角三角形斜边长程序_编写一个程序,输入直角三角形两条直角边a和b的长度,利用勾股定理计算斜边c的长度。要求结果保留2位...
  7. python生成四位随机数_如何使用Python生成4位密码随机数
  8. Tinyproxy 搭建代理记录
  9. 【图文】【linux驱动、imx6ull核心板、FPGA、qt上位机、持续更新中···】打印机项目
  10. JQ点击事件click和on区别