传送门

Luogu

解题思路

考虑 \(\text{DP}\)。

设 \(f[u][k]\) 表示从 \(u\) 到 \(n\) 走过不超过 \(Mindis(u, n) + k\) 距离的方案数。

转移方程为:\(f[u][k] = \sum{f[v][k + Mindis(u,n) - Mindis(v,n) - dis(u,v)]}\)

\(Mindis\) 可以预处理。

无解的情况直接在记搜的时候把 \(-1\) 传上去。

最后输出 \(f[1][k]\) 即可。

细节注意事项

  • 要记得有多组数据,每次都要初始化

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <queue>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= (c == '-'), c = getchar();
while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
s = f ? -s : s;
}
const int _ = 100010;
const int __ = 400010;
int n, m, kk, p;
int tot, head1[_], headn[_], nxt[__], ver[__], w[__];
inline void Add_edge(int u, int v, int d, int* head)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, w[tot] = d; }
struct node{ int val, u; };
inline bool operator < (const node& x, const node& y) { return x.val > y.val; }
int dis[_], vis[_];
priority_queue < node > q;
inline void dijkstra() {
memset(vis, 0, sizeof vis);
memset(dis, 0x3f, sizeof dis);
dis[n] = 0, q.push((node) { 0, n });
while (!q.empty()) {
int u = q.top().u; q.pop();
if (vis[u]) continue; vis[u] = 1;
for (rg int i = headn[u]; i; i = nxt[i]) {
int v = ver[i];
if (dis[v] > dis[u] + w[i])
dis[v] = dis[u] + w[i], q.push((node) { dis[v], v });
}
}
}
int st[_][55], f[_][55];
inline int dfs(int u, int k) {
if (st[u][k]) return -1;
if (f[u][k]) return f[u][k];
st[u][k] = 1;
if (u == n) f[u][k] = 1;
for (rg int i = head1[u]; i; i = nxt[i]) {
int v = ver[i], tmp = dis[v] + w[i] - dis[u];
if (tmp <= k) {
int res = dfs(v, k - tmp);
if (res != -1) f[u][k] = (f[u][k] + res) % p;
else return f[u][k] = -1;
}
}
return st[u][k] = 0, f[u][k];
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
int T; read(T);
while (T--) {
read(n), read(m), read(kk), read(p);
tot = 0;
memset(head1, 0, sizeof head1);
memset(headn, 0, sizeof headn);
for (rg int u, v, d, i = 1; i <= m; ++i)
read(u), read(v), read(d), Add_edge(u, v, d, head1), Add_edge(v, u, d, headn);
dijkstra();
memset(f, 0, sizeof f);
memset(st, 0, sizeof st);
printf("%d\n", dfs(1, kk));
}
return 0;
}

完结撒花 \(qwq\)

「NOIP2017」逛公园的更多相关文章

  1. LOJ2316. 「NOIP2017」逛公园【DP】【最短路】【思维】

    LINK 思路 因为我想到的根本不是网上的普遍做法 所以常数出奇的大,而且做法极其暴力 可以形容是带优化的大模拟 进入正题: 首先一个很显然的思路是如果在合法的路径网络里面存在零环是有无数组解的 然后 ...

  2. 【LOJ2316】「NOIP2017」逛公园

    [题目链接] [点击打开链接] [题目概括] 对给定\(K\),起点\(1\)到终点\(n\)中对长度为\([L,L+K]\)的路径计数. \(L\)为\(1\)到\(n\)的最短路长度. [思路要点 ...

  3. [luogu P3953] [noip2017 d1t3] 逛公园

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

  4. 「WC2013」糖果公园

    「WC2013」糖果公园 传送门 树上带修莫队板子题. 看懂题意后就是板子题了. 参考代码: #include <algorithm> #include <cstdio> #i ...

  5. 「NOIP2017」宝藏

    「NOIP2017」宝藏 题解 博客阅读效果更佳 又到了一年一度NOIPCSP-S 赛前复习做真题的时间 于是就遇上了这道题 首先观察数据范围 \(1 \le n \le 12\) ,那么极大可能性是 ...

  6. 逛公园「NOIP2017」最短路+DP

    大家好我叫蒟蒻,这是我的第一篇信竞题解blog [题目描述] 策策同学特别喜欢逛公园. 公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园 ...

  7. 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索

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

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

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

  9. NOIP2017:逛公园

    Sol 发现\(NOIP2017\)还没\(AK\)??? 赶紧改 考场上明明打出了\(DP\),没时间了,没判环,重点是没初始化数组,爆\(0\) \(TAT\) 先最短路,然后\(f[i][j]\ ...

随机推荐

  1. 【Math】高数-一个有趣的旋转体体积与面积

    Go confidently in the direction of your dreams. Live the life you've imagined. 题目 设曲线 \(y = \tfrac{1 ...

  2. codeforces-1271A - Suits

    A. Suits   A new delivery of clothing has arrived today to the clothing store. This delivery consist ...

  3. P1478

    昨天花一下午时间,把 codeblocks 代码 highlight 改了改,感觉还不错 :) 咳咳.还是说题吧. 这道题利用贪心思想,先去除所有够不着的,然后按使用力气 $ y_i $ 从小到大排序 ...

  4. eclipse配置tomcat后修改server.xml文件(如编码等)无效问题

    我们用eclipse配置好tomcat后,在处理中文乱码或是配置数据源时,我们要修改Tomcat下的server.xml等文件. 修改后重启Tomcat服务器时发现xml文件又被还原了. 因为Tomc ...

  5. jsp用equals判断两个字符串变量是否相等

    使用即可: s1.equals(s2) 如果使用场景: if(s1==s2){} 这样使用可能会出现判断无效的情况. 使用if(s1.equals(s2)){}就可以了.

  6. Deeplearning.ai课程笔记-改善深层神经网络

    目录 一. 改善过拟合问题 Bias/Variance 正则化Regularization 1. L2 regularization 2. Dropout正则化 其他方法 1. 数据变形 2. Ear ...

  7. [BUUCTF 2018]Online Tool

    进入页面 贴出源码 <?php if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $_SERVER['REMOTE_ADDR'] = $_SERVER ...

  8. ubuntu中数据迁移的时候出现ImportError错误

    今天在Flask框架中使用数据库迁移的时候出现了如下错误: ImportError: libmysqlclient.so.20: cannot open shared object file: No ...

  9. Java判断对象是否为Null/空

    package com.taiping.test; import java.lang.reflect.Field; import java.lang.reflect.Type; /** * <p ...

  10. Update(Stage4):Spark原理_运行过程_高级特性

    如何判断宽窄依赖: =================================== 6. Spark 底层逻辑 导读 从部署图了解 Spark 部署了什么, 有什么组件运行在集群中 通过对 W ...