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 行,每行一个整数代表答案。
输入输出样例
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】
对于第一组数据,最短路为 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的方案数. 我们发现如果在最短路上的和零边会有后向性, ...
随机推荐
- 2014-4-5安装python以及基础知识
1.下载安装 从python官网下载python2.7.6 https://www.python.org/download/releases/2.7.6 建议用迅雷下载 会比较快 2.交互式解释器 运 ...
- 开启POP3/SMTP服务
实现发送邮件时需要先启用POP3/SMTP服务(以qq邮箱和网易邮箱启用为例) 一 qq邮箱启用 二.网易邮箱开启POP3/SMTP服务 至此:服务已开启
- Python中表示中文的pattern
Python中表示中文的pattern:[\u4e00-\u9fff] 汉字unicode码表: http://jlqzs.blog.163.com/blog/static/2125298320070 ...
- 【BZOJ2527】Meteors(整体二分)
题意: Byteotian Interstellar Union有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会 ...
- 使用JavaMail通过QQ/126服务器服务发送邮件
https://blog.csdn.net/yidragon88xx/article/details/53230310
- nyoj_10_skiing_201405181748
skiing 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当 ...
- u启动为苹果笔记本重装win7系统教程
准备更换系统的苹果笔记本一台! 上述需要准备的东西均准备好以后我们就开始今天的教程了!! 首先,将已经制作好启动盘的u启动u盘插入到苹果笔记本上的usb插口,然后开机! 由于苹果笔记本电脑 ...
- 条款三:尽量用new和delete而不用malloc和free
malloc和free(及其变体)会产生问题的原因在于它们太简单:他们不知道构造函数和析构函数. 假设用两种方法给一个包含10个string对象的数组分配空间,一个用malloc,另一个用new: s ...
- 慎用Outline ,UGUI Outline实现原理分析
使用 UGUI 制作背包的时候.同事发现假设背包中加入了大量的物品.比方两百个.Unity就会出错,提示 Canvas element contains more than 65535 vertice ...
- Java 实现一个链表
public class MyList { static class Node {// 节点类 Object data; Node next; public Node(Object data) {// ...