【题目】

传送门

题目描述:

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

策策每天都会去逛公园,他总是从 111 号点进去,从 nnn 号点出来。

策策喜欢新鲜的事物,他不希望有两天逛公园的路线完全一样,同时策策还是一个特别热爱学习的好孩子,他不希望每天在逛公园这件事上花费太多的时间。如果 111 号点到 nnn 号点的最短路长为 ddd,那么策策只会喜欢长度不超过 d+kd+kd+k 的路线。

策策同学想知道总共有多少条满足条件的路线,你能帮帮他吗?

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

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

输入格式:

第一行包含一个整数 ttt,代表数据组数。

接下来 ttt 组数据,对于每组数据:

第一行包含四个整数 nnn,mmm,kkk,ppp,每两个整数之间用一个空格隔开。

接下来 mmm 行,每行三个整数 aia_iai​,bib_ibi​,cic_ici​,代表编号为 aia_iai​,bib_ibi​ 的点之间有一条权值为 cic_ici​ 的有向边,每两个整数之间用一个空格隔开。

输出格式:

输出文件包含 ttt 行,每行一个整数代表答案。

样例数据:

输入
2
5 7 2 10
1 2 1
2 4 0
4 5 2
2 3 2
3 4 1
3 5 2
1 5 3
2 2 0 10
1 2 0
2 1 0

输出
3
-1

备注:

【输入输出样例1说明】
对于第一组数据,最短路为 333 。
1−51-51−5,1−2−4−51-2-4-51−2−4−5,1−2−3−51-2-3-51−2−3−5 为 333 条合法路径。

【数据规模与约定】
对于不同的测试点,我们约定各种参数的规模不会超过如下

对于 100%100\%100% 的数据,1≤p≤1091≤p≤10^91≤p≤109;1≤ai,bi≤n1≤a_i,b_i≤n1≤ai​,bi​≤n;0≤ci≤10000≤c_i≤10000≤ci​≤1000。
数据保证:至少存在一条合法的路线。

【分析】

30  pts(k=0)30\; pts(k=0)30pts(k=0):

这部分的分应该是比较容易得到的吧

k=0k=0k=0,转换一下题目意思就是统计最短路个数,由于 k=0k=0k=0 是没有 000 边的,所以还不用判断是否有无穷中路线

不过要注意的是一定要有 visvisvis 数组啊,不然会重复计算的,就错了(被坑了无数次了)

70  pts(70\;pts(70pts(没有 000 边))):

这一部分分是用 dpdpdp 来做的

首先肯定还是要求最短路(这应该是废话)

定义 dis[i]dis[i]dis[i] 为 111 到 iii 的最短路,f[i][j]f[i][j]f[i][j] 为比 dis[i]dis[i]dis[i] 多 jjj 的方案数

现在考虑怎么转移,假如现在 kkk 可以到 iii,边权为 www,并且是从 f[k][x]f[k][x]f[k][x] 转移到 f[i][j]f[i][j]f[i][j]

那么容易得到 x+dis[k]+w−dis[i]=jx+dis[k]+w-dis[i]=jx+dis[k]+w−dis[i]=j,移项得 x=dis[i]−dis[k]+j−wx=dis[i]-dis[k]+j-wx=dis[i]−dis[k]+j−w,那方程就是:

f[i][j]=∑f[k][dis[i]−dis[k]+j−w]f[i][j]=\sum f[k][dis[i]-dis[k]+j-w]f[i][j]=∑f[k][dis[i]−dis[k]+j−w]

(当然如果发现 dis[i]−dis[k]+j−w&lt;0dis[i]-dis[k]+j-w&lt;0dis[i]−dis[k]+j−w<0 了直接跳过就好了)

实际操作的时候用记忆化搜索实现就可以了

100&ThickSpace;pts100\;pts100pts:

现在考虑加上 000 边该怎么办

其实也比较简单,只用再记录一个 vis[i][j]vis[i][j]vis[i][j] 表示 f[i][j]f[i][j]f[i][j] 这个状态出现过没有

如果存在环,从 iii 开始搜索的话(状态是 f[i][j]f[i][j]f[i][j]),就会再次搜到 iii(注意是搜索到 iii,不是回溯到 iii)

那么假设这个环上的其他点为 p1,p2,...,pxp_1,p_2,...,p_xp1​,p2​,...,px​,边权为 w1,w2,...,wxw_1,w_2,...,w_xw1​,w2​,...,wx​,假如回到 iii 的状态依旧是 f[i][j]f[i][j]f[i][j],就说明 w1+w2+...+wx=0w_1+w_2+...+w_x=0w1​+w2​+...+wx​=0(disdisdis 会互相抵消掉),就是 000 环,这时就输出 −1-1−1

【代码】

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define K 55
#define N 100005
#define M 500005
using namespace std;
int n,m,k,p,t1,t2,flag;
int d[N],f[N][K],vis[N][K];
int first[N],v[M],w[M],nxt[M];
int First[N],V[M],W[M],Nxt[M];
priority_queue<pair<int,int> >q;
void add(int x,int y,int z)  {nxt[++t1]=first[x];first[x]=t1;v[t1]=y;w[t1]=z;}
void Add(int x,int y,int z)  {Nxt[++t2]=First[x];First[x]=t2;V[t2]=y;W[t2]=z;}
void init()
{t1=t2=flag=0;memset(f,-1,sizeof(f));memset(first,0,sizeof(first));memset(First,0,sizeof(First));
}
void dijkstra(int s)
{int x,y,i;memset(d,127/3,sizeof(d));q.push(make_pair(0,s));d[s]=0;while(!q.empty()){x=q.top().second;q.pop();for(i=first[x];i;i=nxt[i]){y=v[i];if(d[y]>d[x]+w[i]){d[y]=d[x]+w[i];q.push(make_pair(-d[y],y));}}}
}
int dfs(int now,int val)
{if(~f[now][val])  return f[now][val];int i,to,num;f[now][val]=0,vis[now][val]=1;for(i=First[now];i;i=Nxt[i]){to=V[i];num=d[now]-d[to]+val-W[i];if(num<0)  continue;if(vis[to][num])  flag=1;f[now][val]=(f[now][val]+dfs(to,num))%p;}vis[now][val]=0;return f[now][val];
}
int main()
{int x,y,z,i,T;scanf("%d",&T);while(T--){init();scanf("%d%d%d%d",&n,&m,&k,&p);for(i=1;i<=m;++i){scanf("%d%d%d",&x,&y,&z);add(x,y,z),Add(y,x,z);}int ans=0;dijkstra(1);for(i=0;i<=k;++i)  dfs(n,i);if(flag)  {puts("-1");continue;}memset(f,-1,sizeof(f));f[1][0]=1;for(i=0;i<=k;++i)ans=(ans+dfs(n,i))%p;printf("%d\n",ans);}return 0;
}

【NOIP 2017 提高组】逛公园相关推荐

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

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

  2. NOIP 2017 提高组 初赛

    NOIP 2017 提高组 初赛 做题感悟. 五.完善程序,是本张试卷最简单的题目,两道题做完,大约花了10分钟.2017-10-17 18:25 对了答案,破天荒,全对. 1.(大整数除法) 有如下 ...

  3. NOIP 2017 提高组 K: 奶酪 (SPFA || 并查集)

    K: 奶酪 时间限制: 1 Sec  内存限制: 128 MB 提交: 115  解决: 30 [提交][状态][讨论版] 题目描述 现有一块大奶酪,它的高度为 h ,它的长度和宽度我们可以认为是无限 ...

  4. 【NOIP 2017 提高组 DAY1 T1】小凯的疑惑

    emmm貌似过不了多久就要去考NOIP了,于是我终于开始刷往年的题了 [题目] 题目描述: 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有无数个.在不找零的情况下,仅凭这两种 ...

  5. NOIP 2018提高组复赛C/C++试题及答案详解

    NOIP 2018提高组历年真题 CCF NOIP2018 初赛提高组 C++语言试题 第 1 页,共9 页 第二十四届全国青少年信息学奥林匹克联赛初赛 提高组 C++语言试题 竞赛时间:2018 年 ...

  6. [NOIP 2013提高组]转圈游戏 题解

    这题在洛谷上是道黄题,即[普及/提高-] 所以虽然是提高组的,但是其实挺简单的. 我们来看下题面: [NOIP 2013]转圈游戏 刚看到题面作为一个蒟蒻感觉它都不配做黄题,但是直到我看清楚了后发现它 ...

  7. NOIP 2013 提高组 货车运输

    描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多 ...

  8. NOIP 2008 提高组 复赛 message 传字条

    NOIP 2008 提高组 复赛 message 传字条 1.样例很快模拟成功,但感觉是凑出来的,没有章法. 2.深度优先遍历,但感觉容易超时. 3.动态规划?翻看他人代码,发现动态规划的写法,确实想 ...

  9. NOIP 2015 提高组 初赛

    NOIP 2015 提高组 初赛 疑难点 学习 感悟. 一. 3. 示例如下(来自自个的理解): 101.101 十进制 转十进制1*10^2+0*10^1+1*10^0+1*10^-1+0*10^- ...

最新文章

  1. 在Ubuntu 16.04.3 LTS上玩转quic-go项目
  2. compareto方法_compare方法和compareTo方法区别
  3. docker 容器 defunct 僵尸进程
  4. IMXRT 分散加载文件 修改OCRAM,DTCM、ITCM大小
  5. NYOJ 158 省赛来了
  6. 文件上传服务器经常超时,解决Tomcat文件上传超时问题.
  7. 2011.11.2 try
  8. CAD制图系列之中心线画法
  9. php 查询access数据库操作,php操作access数据库的方法详解
  10. 苹果在中国的审核规律探索一
  11. 网管员的任务与职责漫谈
  12. Smart210使用superboot刷机
  13. pc机箱 图纸_如何升级到新的PC机箱
  14. perfmon 端口修改_Jmeter插件之PerfMon监控插件使用说明
  15. Linux进程间通信(二)之信号量
  16. gitee代码管理仓库管理代码,更简单地查看各阶段的代码变动
  17. 调用百度地图Api,定位到大西洋的问题
  18. SDIO wifi Marvell8801/Marvell88w8801 介绍(七) ---- Marvell8801/Marvell88w8801实现搜索功能
  19. visualGDB下导入cmake工程
  20. 公务员笔试讲义——资料分析1

热门文章

  1. matlab极坐标六边形图片,matlab怎样直接画出六边形
  2. 三次样条曲线插值的基本原理及其C#实现
  3. 【Ruby on Rails全栈课程】3.5 注册功能
  4. 微软的服务器流量计费,微软修改Windows 10更新策略 即使按流量计费也自动更新...
  5. 扩展卡尔曼滤波(EKF)算法详细推导及仿真(Matlab)
  6. Apply pay详解
  7. 国美金融贷款模块解析HTML,国美金融贷款支持网站链接
  8. Fortinet 修复6个高危漏洞
  9. 阿里达摩院python教程真的吗_阿里达摩院出品的459集的python教程,据说懂中文就能入门高清版...
  10. Apkbus不错的源码汇总