题面

这道题是一道不错的计数类DP;

首先我们一定要跑一遍dijkstra来求得每个点到1号点的最短路;

注意题干,题中并没有说所有点都可以到达n好点,只说了存在一条1号点到n号点的路径;所以我们在反向图上BFS求出那些点可以到达n号点;

然后就是dp。我们设计状态:f[u][rest]表示到达u号点时,还可以走额外rest这么长的路;很显然得:f[u][rest]=sigma(f[v][rest-w+dis[v]-dis[u]])

其中dis[u]表示从1到u得最短路;w表示从u到v的边权;

为了在图中DP方便,可以采用记忆化搜索来进行记数;

判断是否输出-1的方法:如果这个状态在栈里,那么输出-1;表示存在0环;

特别注意:当判断-1时,你可能返回-INT_MAX来表示结束程序,但这道题的模数比较小,所以一定不能在返回-INT_MAX时把这个数取模,否则会输出一个负数(不是-INT_MAX),让程序继续进行,并不能输出-1;

#include <bits/stdc++.h>
const int INF=0x7FFFFFFF;
using namespace std;
struct littlestar{
int to;
int nxt;
int w;
}star[400010],star2[400010];
int head[400010],cnt,head2[400010],cnt2;
void add(int u,int v,int w)
{
star[++cnt].to=v;
star[cnt].nxt=head[u];
head[u]=cnt;
star[cnt].w=w;
}
void add2(int u,int v,int w)
{
star2[++cnt2].to=v;
star2[cnt2].nxt=head2[u];
star2[cnt2].w=w;
head2[u]=cnt2;
}
int n,m,k,p;
int dis[100010],vis[100010],bo[100010];
int ans[100010][51];
int st[100010][51];
inline void pre()
{
memset(bo,0,sizeof(bo));
memset(ans,-1,sizeof(ans));
memset(st,0,sizeof(st));
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
memset(head2,0,sizeof(head2));
cnt=0;
cnt2=0;
}
priority_queue<pair<int,int> > q;
void dijkstra()
{
q.push(make_pair(0,1));
dis[1]=0;
while(q.size()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(register int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis[v]>dis[u]+star[i].w){
dis[v]=dis[u]+star[i].w;
q.push(make_pair(-dis[v],v));
}
}
}
}
queue<int> q2;
void panduan()
{
q2.push(n);
bo[n]=1;
while(q2.size()){
int u=q2.front();
q2.pop();
for(register int i=head2[u];i;i=star2[i].nxt){
int v=star2[i].to;
if(bo[v]==0){
q2.push(v);
bo[v]=1;
}
}
}
}
int dp(int u,int rest)
{
if(rest<0) return 0;
if(st[u][rest]==1) return -INF;
if(ans[u][rest]!=-1) return ans[u][rest];
long long tmpans=0;
st[u][rest]=1;
if(u==n) ++tmpans;
for(register int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(bo[v]==0) continue;
int ha=dis[v]-dis[u];
int tmp=dp(v,rest-(star[i].w-ha));
if(tmp==-INF){
return -INF;
}
else{
tmpans=(tmpans+tmp)%p;
}
}
ans[u][rest]=tmpans%p;
st[u][rest]=0;
return tmpans;
}
int main()
{
int t;
cin>>t;
while(t--){
pre();
cin>>n>>m>>k>>p;
for(register int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add2(v,u,w);
}
for(int i=1;i<=n;i++) dis[i]=INF;
dijkstra();
panduan();
long long w=dp(1,k);
if(w==-INF){
cout<<"-1"<<endl;
}
else{
cout<<w<<endl;
}
}
}

NOIP 2017 逛公园 题解的更多相关文章

  1. [NOIp 2017]逛公园

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

  2. NOIP 2017 逛公园 记忆化搜索 最短路 好题

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

  3. 洛谷 P3953 [ NOIP 2017 ] 逛公园 —— 最短路DP

    题目:https://www.luogu.org/problemnew/show/P3953 主要是看题解...还是觉得好难想啊... dfs DP,剩余容量的损耗是边权减去两点最短路差值...表示对 ...

  4. NOIP 2017 逛公园 - 动态规划 - 最短路

    题目传送门 传送门 题目大意 给定一个$n$个点$m$条边的带权有向图,问从$1$到$n$的距离不超过最短路长度$K$的路径数. 跑一遍最短路. 一个点拆$K + 1$个点,变成一个DAG上路径计数问 ...

  5. NOIP2017 逛公园 题解报告 【最短路 + 拓扑序 + dp】

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

  6. [NOIP2017]逛公园 题解

    我连D1T3都不会我联赛完蛋了 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 N 个点 M 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, N 号点是公园的出口,每条边有一个非负 ...

  7. 线段树 || BZOJ1756: Vijos1083 小白逛公园 || P4513 小白逛公园

    题面:小白逛公园 题解: 对于线段树的每个节点除了普通线段树该维护的东西以外,额外维护lsum(与左端点相连的最大连续区间和).rsum(同理)和sum……就行了 代码: #include<cs ...

  8. 【NOIP 2017】逛公园

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

  9. [NOIP 2017 day1]逛公园

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

随机推荐

  1. codevs 1200 同余方程 2012年NOIP全国联赛提高组 x

    /*我在提交的时候发现了一个特别好玩的事,有兴趣的话,可以自己尝试一下:把下面说的地方的y=0改为y=1在codevs里面能够ac,这……数据水?到一定境界……厉害了,吓得我还以为自己对了,结果一讲才 ...

  2. noi.ac #553 序列

    [题目描述] 老虎和蒜头是好朋友. 众所周知,蒜头经常给老虎出一些题目,而老虎也常常被难倒,作为捧杯之王的老虎难免心有怨怼.今天,老虎发现了蒜头的一个序列 a​ .虽然老虎不知道这个序列是用来做什么的 ...

  3. Loooooooooooooooong time no see!

    好久没来啦~去年这会一口气写了好多,是因为即将离职,在公司闲的没事,再加上也积累了一些东西想分享. 最近有个朋友给我私信求助,才又想起这里.这快一年时间,又学习了不少东西.从何写起呢,哈哈,不知道啊~ ...

  4. 关于Additive Ensembles of Regression Trees模型的快速打分预测

    一.论文<QuickScorer:a Fast Algorithm to Rank Documents with Additive Ensembles of Regression Trees&g ...

  5. Codeforces Round #567 (Div. 2) E2 A Story of One Country (Hard)

    https://codeforces.com/contest/1181/problem/E2 想到了划分的方法跟题解一样,但是没理清楚复杂度,很难受. 看了题解觉得很有道理,还是自己太菜了. 然后直接 ...

  6. 连接数据库出现The server time zone value '�й���׼ʱ��' is unrecogni等问题的解决方案

    使用JDBC连接数据库出现The server time zone value '�й���׼ʱ��' is解决方案 ** 将jdbc.properties中url后加入?serverTimezone ...

  7. JSP——常用配置-获取项目跟路径

    将该内容放入一个空白的JSP文件中,保存为basepath.jsp,然后在需要引用的JSP文件中使用include标签引用. <% String path = request.getContex ...

  8. Java-内存模型 final 和 volatile 的内存语义

    前提:内存屏障 内存屏障(Memory Barrier)与内存栅栏(Memory Fence)是同一个概念. 用于阻止指令重排序.保证了特定操作的执行顺序和某些变量的内存可见性. JMM 内存屏障分为 ...

  9. centos7编译安装Python 3.6.8 后用pip3出现SSL未配置问题(import ssl失败)解决方法

    下载源码编译安装openssl https://www.openssl.org/source/openssl-1.0.2j.tar.gz ./config --prefix=/usr/local/op ...

  10. javascript中ClassName属性的详解与实例

    在javascritp中,我们可以通过style属性可以控制元素的样式,从而实现行为层通过DOM的style属性去干预显示层显示的目标,但是这种方法是不好的,而且为了实现通过DOM脚本设置的样式,你不 ...