[luoguP3953] 逛公园(DP + spfa)
看到求方案数,应该很容易想到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)的更多相关文章
- 【题解】NOIP2017逛公园(DP)
[题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...
- P3953 逛公园(dp,最短路)
P3953 逛公园 题目描述 策策同学特别喜欢逛公园.公园可以看成一张NN个点MM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,NN号点是公园的出口,每条边有一个非负权值, 代表策策经 ...
- 【图论 动态规划拆点】luoguP3953 逛公园
经典的动态规划拆点问题. 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 NN 个点 MM 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, NN 号点是公园的出口,每条边有一个非负 ...
- 洛谷 P3953 逛公园【spfa+记忆化dfs+bfs】
spfa预处理出最短路数组dis,然后反向建边bfs出ok[u]表示u能到n点 然后发现有0环的话时候有inf解的,先dfs找0环判断即可 然后dfs,设状态f[u][v]为到u点,还可以跑最短路+v ...
- $[NOIp2017]$ 逛公园 $dp$/记搜
\(Des\) 给定一个有向图,起点为\(1\),终点为\(n\),求和最短路相差不超过\(k\)的路径数量.有\(0\)边.如果有无数条,则输出\(-1\). \(n\leq 10^5,k\leq ...
- 洛谷P3953 逛公园(dp 拓扑排序)
题意 题目链接 Sol 去年考NOIP的时候我好像连最短路计数都不会啊qwq.. 首先不难想到一个思路,\(f[i][j]\)表示到第\(i\)个节点,与最短路之差长度为\(j\)的路径的方案数 首先 ...
- 逛公园[NOIP2017 D2 T3](dp+spfa)
题目描述 策策同学特别喜欢逛公园. 公园可以看成一张 \(N\)个点\(M\) 条边构成的有向图,且没有自环和重边.其中 1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值,代表策策经过这条 ...
- 【洛谷】3953:逛公园【反向最短路】【记忆化搜索(DP)统计方案】
P3953 逛公园 题目描述 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条 ...
- 逛公园「NOIP2017」最短路+DP
大家好我叫蒟蒻,这是我的第一篇信竞题解blog [题目描述] 策策同学特别喜欢逛公园. 公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园 ...
随机推荐
- Fragment(一)--Fragment用法常见问题
fragment notes fragment相关内容包括 基本定义与使用 回退栈内部实现 fragment通信(与activity 与fragment) DialogFragment VP + Fr ...
- https增加临时证书,tomcat配置
1Windows下: 1.1 生成keystore文件及导出证书 打开控制台: 运行: %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RS ...
- java字符串拼接技巧(StringBuilder使用技巧)
在平时的开发中,我们可能会遇到需要拼接如下格式的字符串(至少我是遇到了很多次): 1,2,3,4,5,6,7,8,9,10,11,12,12,12,12,34,234,2134,1234,1324,1 ...
- Hyperledger Fabric on SAP Cloud Platform
今天的文章来自Wen Aviva, 坐Jerry面对面的程序媛. Jerry在之前的公众号文章<在SAP UI中使用纯JavaScript显示产品主数据的3D模型视图>已经介绍过Aviva ...
- 动态规划初步-单向STP
一.题目 给一个m行n列(m <= 10,n <= 100)的整数矩阵,从第一列任何位置出发每次往右.右下.右上走一格,最终达到最后一列.要求经过的整数之和最小.整个矩阵是环形的,即第一行 ...
- 浏览器输入一个url到整个页面显示出来经历了哪些过程?
https://cloud.tencent.com/developer/article/1396399 https://www.cnblogs.com/haonanZhang/p/6362233.ht ...
- k8s 基础概念和术语
Master k8s里的master指的是集群控制节点,每个k8s集群里需要有一个Master节点来负责整个集群的管理和控制,基本k8s所有控制命令都发给它,它负责整个具体的执行过程,后面执行操作基本 ...
- 数据库-SQL语法:GROUP BY与HAVING
注意:select 后的字段,必须要么包含在group by中,要么包含在having 后的聚合函数里. 1. GROUP BY 是分组查询, 一般 GROUP BY 是和聚合函数配合使用. grou ...
- JS中鼠标左右键以及中键的事件
在三维场景中有时候需要判断鼠标的事件,除了使用的click事件,只有鼠标左键有效,而右键无效.而对于onmousedown.onmouseup的时候鼠标的事件左键/右键有效.详细请看w3c上的资料. ...
- ios 团购信息客户端demo(一)
团购信息客户端,主要整合了ASIHTTPREQUEST,KISSXML,AQGridView,MBProgressHUD这几个主要流行的IOS开发库,我们先来看一下效果图 首先我们新建一个IOS工程, ...