传送门

看到求方案数,应该很容易想到dp

f[u][i]表示到点u,且比到u的最短距离多i的方案数

那么需要先预处理dis数组,spfa或者堆优化的dijk

因为考虑到dp的顺序,f[u][i]转移到f[v][j]时,j不可能小于i

所以需要从0到k枚举i,然后从最后一个点开始记忆化搜索

至于判断0环,只需要在记忆化搜索的时候加一个栈即可

1A的代码,哈哈

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 200001 using namespace std; int T, n, m, k, p, cnt, cnt1, ans;
int head[N], to[N], nex[N], val[N], head1[N], to1[N], nex1[N], val1[N], f[N][51], dis[N];
bool flag, vis[N], vis1[N][51], ins[N][51];
queue <int> q; inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
} inline void add(int x, int y, int z)
{
to[cnt] = y;
val[cnt] = z;
nex[cnt] = head[x];
head[x] = cnt++;
} inline void add1(int x, int y, int z)
{
to1[cnt1] = y;
val1[cnt1] = z;
nex1[cnt1] = head1[x];
head1[x] = cnt1++;
} inline void spfa()
{
int i, v, u;
q.push(1);
dis[1] = 0;
while(!q.empty())
{
u = q.front();
q.pop();
vis[u] = 0;
for(i = head[u]; ~i; i = nex[i])
{
v = to[i];
if(dis[v] > dis[u] + val[i])
{
dis[v] = dis[u] + val[i];
if(!vis[v])
{
q.push(v);
vis[v] = 1;
}
}
}
}
} inline void init()
{
int i, x, y, z;
n = read();
m = read();
k = read();
p = read();
for(i = 1; i <= m; i++)
{
x = read();
y = read();
z = read();
add(x, y, z);
add1(y, x, z);
}
spfa();
f[1][0] = 1;
} inline void clear()
{
cnt = cnt1 = ans = flag = 0;
memset(head, -1, sizeof(head));
memset(head1, -1, sizeof(head1));
memset(vis, 0, sizeof(vis));
memset(dis, 127, sizeof(dis));
memset(f, 0, sizeof(f));
memset(vis1, 0, sizeof(vis1));
memset(ins, 0, sizeof(ins));
} inline int dfs(int u, int i)
{
int j, v;
if(i < 0 || flag) return 0;
if(ins[u][i]) return flag = 1;
if(vis1[u][i]) return f[u][i];
ins[u][i] = 1;
for(j = head1[u]; ~j; j = nex1[j])
{
v = to1[j];
f[u][i] = (f[u][i] + dfs(v, dis[u] + i - val1[j] - dis[v])) % p;
}
vis1[u][i] = 1;
ins[u][i] = 0;
return f[u][i];
} inline int solve()
{
int i, t;
for(i = 0; i <= k; i++)
{
t = dfs(n, i);
if(flag) return -1;
ans = (ans + t) % p;
}
return ans;
} int main()
{
T = read();
while(T--)
{
clear();
init();
printf("%d\n", solve());
}
return 0;
}

  

[luoguP3953] 逛公园(DP + spfa)的更多相关文章

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

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

  2. P3953 逛公园(dp,最短路)

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

  3. 【图论 动态规划拆点】luoguP3953 逛公园

    经典的动态规划拆点问题. 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 NN 个点 MM 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, NN 号点是公园的出口,每条边有一个非负 ...

  4. 洛谷 P3953 逛公园【spfa+记忆化dfs+bfs】

    spfa预处理出最短路数组dis,然后反向建边bfs出ok[u]表示u能到n点 然后发现有0环的话时候有inf解的,先dfs找0环判断即可 然后dfs,设状态f[u][v]为到u点,还可以跑最短路+v ...

  5. $[NOIp2017]$ 逛公园 $dp$/记搜

    \(Des\) 给定一个有向图,起点为\(1\),终点为\(n\),求和最短路相差不超过\(k\)的路径数量.有\(0\)边.如果有无数条,则输出\(-1\). \(n\leq 10^5,k\leq ...

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

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

  7. 逛公园[NOIP2017 D2 T3](dp+spfa)

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

  8. 【洛谷】3953:逛公园【反向最短路】【记忆化搜索(DP)统计方案】

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

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

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

随机推荐

  1. ef导航属性

    https://msdn.microsoft.com/en-us/data/jj574232.aspx  场景是   A表中有B,B表中又C.都是一堆多的关系.怎样Mapping是个问题啊.  var ...

  2. Highcharts在IE8中不能一次性正常显示的一种解决办法

    由于客户要求必须在IE浏览器下兼容图表,故选用了兼容性较好的Highcharts.另外说一句,博主尝试过ichartjs.ECharts.YUI,兼容性都没有Highcharts给力(所有的兼容性问题 ...

  3. 【MYSQL】mysql-5.6.19-win32免安装版本配置方法

    [MYSQL]mysql-5.6.19-win32免安装版本配置方法 1.文件下载网站(http://dev.mysql.com/downloads/): 具体下载地址:http://211.136. ...

  4. SAP C/4HANA到底包含哪些产品?

    2018年6月的SAPPHIRE(蓝宝石大会)上, SAP发布了新的商务软件套件:C/4HANA,意在通过SAP C/4HANA将前台应用和SAP Digital Core(数字化核心)S/4HANA ...

  5. Gym 100342F Move to Front (树状数组动态维护和查询)

    用树状数组动态和查询修改排名. 树状数组可以很方便地查询前缀和,那么可以利用这一特点,记录一个点在树状数组里最后一次出现的位置, 查询出这个位置,就可以知道这个点的排名了.更改这个点的排名的时候只要把 ...

  6. PyTorch在NLP任务中使用预训练词向量

    在使用pytorch或tensorflow等神经网络框架进行nlp任务的处理时,可以通过对应的Embedding层做词向量的处理,更多的时候,使用预训练好的词向量会带来更优的性能.下面分别介绍使用ge ...

  7. msys2 使用指定boost

    pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-openssl mingw-w64- ...

  8. jsTree展开根节点 设置用户图标

    $("#jstree").on("loaded.jstree", function (event, data) { var n = 0; var root = ...

  9. Bootstrap历练实例:基本输入框组

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  10. Bootstrap 网格系统(Grid System)实例5

    Bootstrap 网格系统(Grid System)实例5:手机,平板电脑,笔记本或台式电脑 <!DOCTYPE html><html><head><met ...