NOIP 2017 逛公园
策策同学特别喜欢逛公园。公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边。其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间。
策策每天都会去逛公园,他总是从1号点进去,从N号点出来。
策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间。如果1号点 到NN号点的最短路长为d,那么策策只会喜欢长度不超过d+K的路线。
策策同学想知道总共有多少条满足条件的路线,你能帮帮它吗?
为避免输出过大,答案对P取模。
如果有无穷多条合法的路线,请输出−1。
去年的考试题,考场上没有想到,连DFS都打错了
首先来看k=0的情况,就是一个裸的最短路计数
然后是正解,我们有最短路计数可以想到正解肯定是个DP
dp[i][j]代表的是从1号点到i号点,满足需要比最短路多走j的长度的路线的数量
因为k的最大值是50,所以可以开状态
然后来看具体如何实现,我们先SPFA求出单源最短路
然后反向建图,这样可以避免走进死路
然后会发现DP直接写并不好实现,因为转移顺序不好确定
于是想到记忆化搜索,需要那个就转移
因为DP状态已经设好了
所以只需要转移,每一次我们对于每条边进行操作
对于边u->v 权值为w
我们可以通过刚才求出来的最短路来计算出从1到v还需要多走多长的路
也就是dis[u]-dis[v]+j-w j为当前还需要多走的长度 (注意,此时的u,v是在反向图中的)
然后求和即可
下面给出代码:(注意赋初值)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; inline long long rd(){long long x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';return x*f; } inline void write(long long x){if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0');return ; } long long n,m,k,mod; long long head[1000006]; long long nxt[2000006],to[2000006]; long long v[2000006]; long long total=0; void add(long long x,long long y,long long z){total++;v[total]=z;to[total]=y;nxt[total]=head[x];head[x]=total;return ; } long long q[1000006]; long long l=0,r=0; long long book[1000006]; long long dis[1000006]; void spfa(long long x){memset(dis,127,sizeof(dis));memset(book,0,sizeof(book));l=0,r=0;book[x]=1;dis[x]=0;q[++r]=x;while(l<r){long long h=q[++l];book[h]=0;for(long long e=head[h];e;e=nxt[e]){if(dis[to[e]]>dis[h]+v[e]){dis[to[e]]=dis[h]+v[e];if(!book[to[e]]){q[++r]=to[e];book[to[e]]=1;}}}book[h]=0;}return ; } long long f[100006][56]; long long vis[100006][56]; long long head2[200006]; long long to2[200006]; long long nxt2[200006]; long long v2[200006]; long long total2=0; void add2(long long x,long long y,long long z){total2++;to2[total2]=y;v2[total2]=z;nxt2[total2]=head2[x];head2[x]=total2;return ; } long long set=0; long long dfs(long long x,long long y){if(f[x][y]!=-1) return f[x][y];vis[x][y]=1;f[x][y]=0;for(long long e=head2[x];e;e=nxt2[e]){long long h1=to2[e],h2=dis[x]-dis[to2[e]]-v2[e]+y;if(h2>=0){if(vis[h1][h2]) set=1;int num=dfs(h1,h2);f[x][y]=(f[x][y]+num)%mod;}}vis[x][y]=0;return f[x][y]; } int main(){long long T=rd();while(T--){memset(head,0,sizeof(head));memset(head2,0,sizeof(head2));total=total2=0;n=rd(),m=rd(),k=rd(),mod=rd();for(long long i=1;i<=m;i++){long long x=rd(),y=rd(),z=rd();add(x,y,z),add2(y,x,z);}spfa(1);memset(f,-1,sizeof(f));memset(vis,0,sizeof(vis));f[1][0]=1;long long ans=0;set=0;for(long long i=0;i<=k;i++){ans=(ans+dfs(n,i))%mod;}dfs(n,k+1);if(!set) write(ans%mod),puts("");else write(-1),puts("");}return 0; }
转载于:https://www.cnblogs.com/WWHHTT/p/9903958.html
NOIP 2017 逛公园相关推荐
- NOIP 2017 逛公园 记忆化搜索 最短路 好题
题目描述: 策策同学特别喜欢逛公园.公园可以看成一张N个点MM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. ...
- 【NOIP 2017 提高组】逛公园
[题目] 传送门 题目描述: 策策同学特别喜欢逛公园.公园可以看成一张 nnn 个点 mmm 条边构成的有向图,且没有自环和重边.其中 111 号点是公园的入口,nnn 号点是公园的出口,每条边有一个 ...
- 2017noip逛公园
2017 noip Day1 T2 逛公园 (洛谷P3953)传送门 输出输入数据自己找 这个题看到其他的大佬有用dp做的. 推荐一个大佬的讲解 本蒟蒻dp学得烂,东拼拼西凑凑勉强懂了.就发一个dfs ...
- TYVJ1427 小白逛公园
P1427 小白逛公园 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦-在小新家附近有一条"公园路&qu ...
- 【游记】NOIP 2017
时间:2017.11.11~2017.11.12 地点:广东省广州市第六中学 Day1 T1:看到题目,心想这种题目也能放在T1? 这个结论我之前遇到过至少3次,自己也简单证明过.初见是NOIP200 ...
- JZOJ 5475. 【NOIP2017提高组正式赛】逛公园
Description 策策同学特别喜欢逛公园.公园可以看成一张n个点m条边构成的有向图,且没有自环和重边.其中1号点是公园的入口,n号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花的 ...
- 牛客小白月赛12 I 华华和月月逛公园 (tarjian 求桥)
链接:https://ac.nowcoder.com/acm/contest/392/I 来源:牛客网 华华和月月逛公园 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K, ...
- 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索
题目描述 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策 ...
- 【ybt高效进阶4-4-3】【luogu P4513】公园遛狗 / 小白逛公园
公园遛狗 / 小白逛公园 题目链接:ybt高效进阶4-4-3 / luogu P4513 题目大意 给你一个序列,要维护两个操作. 单点修改和在一个区间中找权值最大的子区间的权值. 思路 其实这个是很 ...
最新文章
- 双调整!清华大学迎来新任书记、校长
- 20145328《网络对抗》Web基础
- 使用Ant Design 和Vue,React中后台开发套餐
- JDK1.8 Lambda 使用详解(转)
- Win10怎么设置虚拟内存?
- 项目实战|100个蓝牙接收器发货了
- 南通大学计算机组成原理期末考试题,南通大学计算机组成原理期末考试范围.docx...
- 设置字段权限_命令行快速提示:权限进阶
- oracle 修改 回话数,Oracle命令--修改oracle回话数
- 【机器学习_2】机器学习资料
- 【设计模式】-工厂模式->简单工厂模式(源码与类图解析)
- sheng的学习笔记-mysql框架原理
- Renew 、Revive 、Renovate、Update、Refresh区别
- 小程序转uni-app——引入组件显示问题
- 这款耳机的性价比堪比AirPods,写代码的你可以看看
- Web基础-JSON和AJAX
- Unity3D 2021.1.1F1。更新与下载。
- PreTranslateMessage和TranslateMessage区别
- 解决windows 2000无法安装vmtool的问题
- C语言文件读写操作,写入数据到文件