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: 复制

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
输出样例#1: 复制

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,最短路)的更多相关文章

  1. 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]表示在被选择的集合当中. 大力记忆化搜索就行了. ...

  2. 洛谷P3953 逛公园(dp 拓扑排序)

    题意 题目链接 Sol 去年考NOIP的时候我好像连最短路计数都不会啊qwq.. 首先不难想到一个思路,\(f[i][j]\)表示到第\(i\)个节点,与最短路之差长度为\(j\)的路径的方案数 首先 ...

  3. [Luogu P3953] 逛公园 (最短路+拓扑排序+DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易 ...

  4. Luogu P3953 逛公园(最短路+记忆化搜索)

    P3953 逛公园 题面 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园的入口,\(N\) 号点是公 ...

  5. 【题解】NOIP2017逛公园(DP)

    [题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n​节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...

  6. 【NOIP2017】逛公园(最短路图,拓扑排序,计数DP)

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

  7. LOJ P3953 逛公园 NOIP dp 最短路 拓扑排序

    https://www.luogu.org/problemnew/show/P3953 开o2过了不开o2re一个点...写法如题 顺便一提这道题在我校oj是a不了的因为我校土豆服务器速度奇慢1s时限 ...

  8. 洛谷P3953 逛公园 [noip2017] 图论+dp

    正解:图论(最短路)+dp(记忆化搜索) 解题报告: 这题真的是个好东西! 做了这题我才发现我的dij一直是错的...但是我以前用dij做的题居然都A了?什么玄学事件啊...我哭了TT 不过其实感觉还 ...

  9. NOIP2017 Day1 T3 逛公园(最短路+拓扑排序+DP)

    神tm比赛时多清个零就有60了T T 首先跑出1起点和n起点的最短路,因为k只有50,所以可以DP.设f[i][j]表示比最短路多走i的长度,到j的方案数. 我们发现如果在最短路上的和零边会有后向性, ...

随机推荐

  1. conflunce安装配置

    下载 下载Confluence-v5.4.4.zip包,其中包含   atlassian-confluence-5.4.4-x64.bin #程序二进制文件 confluence5.x-crack.z ...

  2. BNUOJ 5235 Starship Troopers

    Starship Troopers Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Origi ...

  3. 关于OPENSSL的EVP函数的使用

    4月份没什么做,就是做了OPENSSL的 加密和解密的应用,现在公开一下如何调用OPENSSL对字符串进行加密和解密,当中也学会了对加密数据进行BASE64编码,现在公开一下代码,在这感谢GITHUB ...

  4. css3 & background & background-image

    css3 & background & background-image https://developer.mozilla.org/en-US/docs/Web/CSS/backgr ...

  5. LA3263 一笔画

    题目大意:依次给定多个点(要求第一个点和最后一个点重叠),把前后两个点相连求最后得到的图形的面的个数 根据欧拉定理: 设平面图的顶点数为V,边数为E,面数为F,则V+F-E = 2 这里的E是指如果一 ...

  6. noip模拟赛 终末

    分析:举个例子就能发现:偶数位上的数都必须是0,奇数位上的数可以取0~k-1,这就是一个标准的数位dp了. 这编译器......数组越界了竟然不报错. #include <cstdio> ...

  7. Big String(poj 2887)

    题意: 给你一个不超过1e6的字符串,和不超过2000次的操作 操作分为两种: 1.将一个字符插入到某个位置的前面 2.询问当前位置的字符 /* 块状链表模板水题(我的智商也就能做这种题了). 观察题 ...

  8. codevs4439 YJQ Requires Food

    题目描述 Description 神犇YJQ有n个不同的妹子和m种食物,每一天每一种食物只供应一个妹子吃的份量.在接下来的t天内,YJQ准备包养所有的妹子. 对于每个妹子,她在t天内都只会吃某些特定的 ...

  9. How many ways?? 矩阵快速幂 邻接矩阵意义

    春天到了, HDU校园里开满了花, 姹紫嫣红, 非常美丽. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这迷人的校园, 葱头决定, 每次上课都走不同的路线去教室 ...

  10. Hive之Order,Sort,Cluster and Distribute By

    测试数据 create table sort_test( id int, name string ) row format delimited fields terminated by '\t' li ...