P3953 逛公园(dp,最短路)
P3953 逛公园
题目描述
策策同学特别喜欢逛公园。公园可以看成一张NN个点MM条边构成的有向图,且没有 自环和重边。其中1号点是公园的入口,NN号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间。
策策每天都会去逛公园,他总是从1号点进去,从NN号点出来。
策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间。如果1号点 到NN号点的最短路长为dd,那么策策只会喜欢长度不超过d + Kd+K的路线。
策策同学想知道总共有多少条满足条件的路线,你能帮帮它吗?
为避免输出过大,答案对PP取模。
如果有无穷多条合法的路线,请输出-1−1。
输入输出格式
输入格式:
第一行包含一个整数 TT, 代表数据组数。
接下来TT组数据,对于每组数据: 第一行包含四个整数 N,M,K,PN,M,K,P,每两个整数之间用一个空格隔开。
接下来MM行,每行三个整数a_i,b_i,c_iai,bi,ci,代表编号为a_i,b_iai,bi的点之间有一条权值为 c_ici的有向边,每两个整数之间用一个空格隔开。
输出格式:
输出文件包含 TT 行,每行一个整数代表答案。
输入输出样例
说明
【样例解释1】
对于第一组数据,最短路为 33。 $1 – 5, 1 – 2 – 4 – 5, 1 – 2 – 3 – 5$ 为 33 条合法路径。
【测试数据与约定】
对于不同的测试点,我们约定各种参数的规模不会超过如下
测试点编号 | TT | NN | MM | KK | 是否有0边 |
---|---|---|---|---|---|
1 | 5 | 5 | 10 | 0 | 否 |
2 | 5 | 1000 | 2000 | 0 | 否 |
3 | 5 | 1000 | 2000 | 50 | 否 |
4 | 5 | 1000 | 2000 | 50 | 否 |
5 | 5 | 1000 | 2000 | 50 | 否 |
6 | 5 | 1000 | 2000 | 50 | 是 |
7 | 5 | 100000 | 200000 | 0 | 否 |
8 | 3 | 100000 | 200000 | 50 | 否 |
9 | 3 | 100000 | 200000 | 50 | 是 |
10 | 3 | 100000 | 200000 | 50 | 是 |
对于 100%的数据, 1 \le P \le 10^9,1 \le a_i,b_i \le N ,0 \le c_i \le 10001≤P≤109,1≤ai,bi≤N,0≤ci≤1000。
数据保证:至少存在一条合法的路线。
- #include<bits/stdc++.h>
- #define b 1000007
- #define ll long long
- using namespace std;
- ll n,m,k,p,ans,cnt;
- ll head[b],dis[b],C[b];
- ll vis[b];
- struct edge{
- ll u,v,net,w;
- }e[b<<];
- queue<ll>q;
- inline void add(int u,int v,int w)
- {
- e[++cnt].v=v;e[cnt].w=w;e[cnt].net=head[u];head[u]=cnt;
- }
- inline ll read()
- {
- ll x=,f=;char c=getchar();
- while(c>''||c<''){if(c=='-')f=-;c=getchar();}
- while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
- return x*f;
- }
- void spfa(int u)
- {
- dis[u]=;vis[u]=;C[u]=;q.push(u);
- while(!q.empty())
- {
- int now=q.front();q.pop();
- vis[now]=;
- for(int i=head[now];i;i=e[i].net)
- {
- int v=e[i].v;
- if(dis[v]>dis[now]+e[i].w)
- {
- dis[v]=dis[now]+e[i].w;
- C[v]=C[u];
- if(!vis[v]) vis[v]=,q.push(v);
- }
- else if(dis[v]==dis[now]+e[i].w)
- {
- if(!vis[v]) vis[v]=,q.push(v);
- C[v]+=C[u];C[v]%=p;
- }
- }
- }
- }
- void clear()
- {
- memset(C,,sizeof C);
- memset(dis,/,sizeof dis);
- memset(vis,,sizeof vis);
- memset(head,,sizeof head);
- memset(e,,sizeof e);
- while(!q.empty()) q.pop();
- cnt=;
- }
- int main()
- {
- int T;T=read();
- while(T--)
- {
- clear();
- n=read();m=read();k=read();p=read();
- int x,y,z;
- for(int i=;i<=m;i++)
- {
- x=read();y=read();z=read();
- add(x,y,z);
- }
- spfa();C[n]%=p;
- cout<<C[n]<<endl;
- }
- }
20暴力
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<queue>
- #define N 200007
- using namespace std;
- int T,b,n,m,k,mod,cnt,head[N];
- int from[N],to[N],w[N];
- int dis[N],vis[N],dp[N][];
- int in[N],re[N],flag;
- struct edge{
- int next,to,w;
- }e[N<<];
- queue<int>q;
- inline int read()
- {
- int x=,f=;char c=getchar();
- while(c>''||c<''){if(c=='-')f=-;c=getchar();}
- while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
- return x*f;
- }
- void add(int x,int y,int w)
- {
- e[++cnt]=(edge){head[x],y,w};
- head[x]=cnt;
- }
- int DFS(int x,int res)//返回到达x点还剩res步可以绕的方案数
- {
- if(~dp[x][res]) return dp[x][res];
- dp[x][res]=(x==);
- for(int i=head[x];i;i=e[i].next)
- {
- int R=e[i].to;
- int tt=res-((dis[R]+e[i].w)-dis[x]);//通过这条边多绕了一会
- if(tt<) continue;
- if(in[R]&&re[R]==tt) flag=;//如果说res一直没有减少的情况下搜出来一个圈,说明有0环
- else in[R]=,re[R]=tt;
- (dp[x][res]+=DFS(R,tt))%=mod;
- in[R]=;re[R]=;
- }
- return dp[x][res];
- }
- void Work()
- {
- memset(head,,sizeof(head));cnt=;
- b=read();m=read();k=read();mod=read();
- for(int i=;i<=m;i++)
- {
- from[i]=read();to[i]=read();w[i]=read();
- add(from[i],to[i],w[i]);
- }
- memset(dis,,sizeof(dis));
- q.push();dis[]=;vis[]=;
- while(!q.empty())
- {
- int x=q.front();
- for(int i=head[x];i;i=e[i].next)
- {
- int R=e[i].to;
- if(dis[R]<=dis[x]+e[i].w) continue;
- dis[R]=dis[x]+e[i].w;
- if(!vis[R]) vis[R]=,q.push(R);
- }
- q.pop();vis[x]=;
- }
- memset(head,,sizeof(head));cnt=;
- memset(dp,-,sizeof(dp));flag=;
- for(int i=;i<=m;i++)
- add(to[i],from[i],w[i]);
- DFS(b,k);
- printf("%d\n",flag?-:DFS(b,k));
- }
- int main()
- {
- T=read();
- while(T--)Work();
- return ;
- }
P3953 逛公园(dp,最短路)的更多相关文章
- 2018.11.01 洛谷P3953 逛公园(最短路+dp)
传送门 设f[i][j]f[i][j]f[i][j]表示跟最短路差值为iii当前在点jjj的方案数. in[i][j]in[i][j]in[i][j]表示在被选择的集合当中. 大力记忆化搜索就行了. ...
- 洛谷P3953 逛公园(dp 拓扑排序)
题意 题目链接 Sol 去年考NOIP的时候我好像连最短路计数都不会啊qwq.. 首先不难想到一个思路,\(f[i][j]\)表示到第\(i\)个节点,与最短路之差长度为\(j\)的路径的方案数 首先 ...
- [Luogu P3953] 逛公园 (最短路+拓扑排序+DP)
题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易 ...
- Luogu P3953 逛公园(最短路+记忆化搜索)
P3953 逛公园 题面 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园的入口,\(N\) 号点是公 ...
- 【题解】NOIP2017逛公园(DP)
[题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...
- 【NOIP2017】逛公园(最短路图,拓扑排序,计数DP)
题意: 策策同学特别喜欢逛公园. 公园可以看成一张 N 个点 M 条边构成的有向图,且没有自环和重边.其中 1 号点是公园的入口, N 号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花 ...
- LOJ P3953 逛公园 NOIP dp 最短路 拓扑排序
https://www.luogu.org/problemnew/show/P3953 开o2过了不开o2re一个点...写法如题 顺便一提这道题在我校oj是a不了的因为我校土豆服务器速度奇慢1s时限 ...
- 洛谷P3953 逛公园 [noip2017] 图论+dp
正解:图论(最短路)+dp(记忆化搜索) 解题报告: 这题真的是个好东西! 做了这题我才发现我的dij一直是错的...但是我以前用dij做的题居然都A了?什么玄学事件啊...我哭了TT 不过其实感觉还 ...
- NOIP2017 Day1 T3 逛公园(最短路+拓扑排序+DP)
神tm比赛时多清个零就有60了T T 首先跑出1起点和n起点的最短路,因为k只有50,所以可以DP.设f[i][j]表示比最短路多走i的长度,到j的方案数. 我们发现如果在最短路上的和零边会有后向性, ...
随机推荐
- 九度oj 题目1202:排序
题目1202:排序 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:28802 解决:9408 题目描述: 对输入的n个数进行排序并输出. 输入: 输入的第一行包括一个整数n(1<=n ...
- 前端开发:JQuery(2)& Bootstrap
JS事件流 事件的概念:HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件.页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件. 事件流: ...
- Linux下汇编语言学习笔记14 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- VS调试STL问题总结
---恢复内容开始--- 以前写代码总觉用自己写的东西比较牛逼,vector?stack?为什么不自己实现.后来才认识到这是个幼稚的想法!首先每次都自己实现是一种重复劳动:其次,自己写的话很难保证没有 ...
- KMP算法 C#实现 字符串查找简单实现
KMP算法 的C#实现,初级版本 static void Main(string[] args) { #region 随机字符 StringBuilder sb = new StringBuilder ...
- javaweb开发页面数字过长显示科学计数法的问题
1. 检查该字段是否为double类型,如果是,请改成BigDecimal 2.如果是导出excel里面为科学计数法,原页面正常,是因为excel设置的原因,请参考https://jingyan.ba ...
- 洛谷 P2033 Chessboard Dance
P2033 Chessboard Dance 题目描述 在棋盘上跳舞是件有意思的事情.现在给你一张国际象棋棋盘和棋盘上的一些子以及你的初始位置和方向.求按一定操作后,棋盘的状态. 操作有四种,描述如下 ...
- 选择器的使用(root选择器)
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta ...
- java压缩与解压文件
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import ...
- POJ 1849 Two(遍历树)
POJ 1849 Two(遍历树) http://poj.org/problem?id=1849 题意: 有一颗n个结点的带权的无向树, 在s结点放两个机器人, 这两个机器人会把树的每条边都走一遍, ...