记忆化搜索

跑一次反向的最短路求出MinDis(u,n)MinDis(u,n)MinDis(u,n)

f[u][k]f[u][k]f[u][k]表示dis(u,n)&lt;=MinDis(u,n)+dis(u,n)&lt;=MinDis(u,n)+kdis(u,n)&lt;=MinDis(u,n)+dis(u,n)&lt;=MinDis(u,n)+kdis(u,n)<=MinDis(u,n)+dis(u,n)<=MinDis(u,n)+k的方案数,答案就是f[1][K]f[1][K]f[1][K]

考虑egde(u,v,w)egde(u,v,w)egde(u,v,w)

同样的道理走这条边的话, dis(v,n)=MinDis(v,n)+w−MinDis(u,n)dis(v,n)=MinDis(v,n)+w-MinDis(u,n)dis(v,n)=MinDis(v,n)+w−MinDis(u,n)

f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]f[u][k]=∑f[v][k-(MinDis(v,n)-MinDis(u,n)+w)]f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]

⇒f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]f[u][k]=∑f[v][k−(MinDis(v,n)−MinDis(u,n)+w)]

这样怎么判000环呢?只要在搜索的时候记录个instackinstackinstack就okokok了

如果当前的转状态还在搜索的栈中就可以直接返回−1-1−1了

AC code:

#include<bits/stdc++.h>
using namespace std; inline void read(int &num)
{
char ch; int flag=1;
while(!isdigit(ch=getchar()))if(ch=='-')flag=-flag;
for(num=ch-'0';isdigit(ch=getchar());num=num*10+ch-'0');
num*=flag;
} const int MAXN = 100005;
const int MAXM = 200005;
const int MAXK = 55; int n, m, k, p, f[MAXN][MAXK];
bool instk[MAXN][MAXK]; int fir[MAXN], to[MAXM], nxt[MAXM], wt[MAXM], cnt;
int rfir[MAXN], rto[MAXM], rnxt[MAXM], rwt[MAXM], rcnt; inline void Add(int u, int v, int w) { to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; wt[cnt] = w; }
inline void rAdd(int u, int v, int w) { rto[++rcnt] = v; rnxt[rcnt] = rfir[u]; rfir[u] = rcnt; rwt[rcnt] = w; } int dis[MAXN];
bool inq[MAXN];
queue<int>Q;
void spfa(int T)
{
memset(dis, 0x7f, sizeof dis);
dis[T] = 0; inq[T] = 1; Q.push(T);
while(!Q.empty())
{
int u = Q.front(); inq[u] = 0; Q.pop();
for(int i = rfir[u]; i; i = rnxt[i])
if(dis[rto[i]] > dis[u] + rwt[i])
{
dis[rto[i]] = dis[u] + rwt[i];
if(!inq[rto[i]])
inq[rto[i]] = 1, Q.push(rto[i]);
}
}
} int dfs(int u, int now)
{
if(instk[u][now]) return -1;
if(f[u][now]) return f[u][now];
instk[u][now] = 1;
if(u == n) f[u][now] = 1;
for(int i = fir[u], tmp; i; i = nxt[i])
if(dis[to[i]]-dis[u]+wt[i] <= now)
{
if((tmp=dfs(to[i], now-dis[to[i]]+dis[u]-wt[i])) == -1) return f[u][now] = -1;
(f[u][now] += tmp) %= p;
}
return instk[u][now] = 0, f[u][now];
} int main ()
{
int T, x, y, z;
read(T);
while(T--)
{
memset(f, 0, sizeof f);
memset(instk, 0, sizeof instk);
memset(fir, 0, sizeof fir); cnt = 0;
memset(rfir, 0, sizeof fir); rcnt = 0;
read(n), read(m), read(k), read(p);
for(int i = 1; i <= m; i++)
{
read(x), read(y), read(z);
Add(x, y, z), rAdd(y, x, z);
}
spfa(n);
printf("%d\n", dfs(1, k));
}
}

【NOIP2017】逛公园 D1 T3的更多相关文章

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

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

  2. [NOIP2017] 逛公园

    [NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^ ...

  3. 【比赛】NOIP2017 逛公园

    考试的时候灵光一闪,瞬间推出DP方程,但是不知道怎么判-1,然后?然后就炸了. 后来发现,我只要把拓扑和DP分开,中间加一个判断,就AC了,可惜. 看这道题,我们首先来想有哪些情况是-1:只要有零环在 ...

  4. NOIP2017逛公园(dp+最短路)

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

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

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

  6. [NOIP2017]逛公园 题解

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

  7. [NOIP2017] 逛公园 解题报告(DP)

    我很不想说 在我的AC代码上我打了表,但实在没有办法了.莫名的8,9个点RE.然而即便是打表...也花了我很久. 这大概是NOIP2017最难的题了,为了让不懂的人更容易理解,这篇题解会比较详细 我的 ...

  8. Luogu P3953 [NOIP2017]逛公园

    题目 首先我们跑出从\(1\)出发的最短路\(d1\)和反图上从\(n\)出发的最短路\(dn\). 然后我们处理出长度不超过\(d1_n+k\)的最短路边集,给它拓扑排序. 如果存在环,那么这个环一 ...

  9. [NOIP2017] 逛公园 【最短路】【强连通分量】

    题目分析: 首先考虑无数条的情况.出现这种情况一定是一条合法路径经过了$ 0 $环中的点.那么预先判出$ 0 $环中的点和其与$ 1 $和$ n $的距离.加起来若离最短路径不超过$ k $则输出$ ...

随机推荐

  1. Centos7 yum方式安装MySQL

    1.下载安装源 wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm 2.yum方式安装 yu ...

  2. Oracle数据库Schema的简介

    百度文库中 Schema 的解释: 数据库中的Schema,为数据库对象的集合,一个用户一般对应一个schema. 官方定义如下: A schema is a collection of databa ...

  3. git 学习笔记 --- Rebase

    在上一节我们看到了,多人在同一个分支上协作时,很容易出现冲突.即使没有冲突,后push的童鞋不得不先pull,在本地合并,然后才能push成功. 每次合并再push后,分支变成了这样: $ git l ...

  4. ECharts折线图堆叠设置为不堆叠的方法

    下图是ECharts折线图堆叠的官方源码,设置折线图不堆叠只需要将每一个stack的值设置为不一样的名称或者将stack属性删除即可. option = { title: { text: '折线图堆叠 ...

  5. React 语法

    1.JavaScript XML JSX = JavaScript XML,是一个看起来很像 XML 的 JavaScript 语法扩展.JSX 不是模板,是JS语法本身,有更多的扩展.JSX 组件一 ...

  6. Thymeleaf前后端分页查询

    分页查询是一个很常见的功能,对于分页也有很多封装好的轮子供我们使用. 比如使用mybatis做后端分页可以用Pagehelper这个插件,如果使用SpringDataJPA更方便,直接就内置的分页查询 ...

  7. Mybatis中使用association及collection进行自关联示例(含XML版与注解版)

    XML版本: 实体类: @Data @ToString @NoArgsConstructor public class Dept { private Integer id; private Strin ...

  8. MySQL数据库汇总

    -- mysql的最大连接数:默认为 100   -- mysql的增删改查   -- mysql统计各个字段(case when 用法 注:也可以使用其他的)   select (case when ...

  9. Linux下which、whereis、locate、find命令作用

    1 which 查看可执行文件的位置,也可以找到命令别名 2 whereis 查看文件的位置 3 locate 系统数据库查找文件位置,数据库大约每天更新一次 4 find 根据查找条件,搜寻硬盘查询 ...

  10. Django:实现读写分离

    库的配置 1.读写分离 settings配置 #settings.py 配置库信息,生成2个库 DATABASES = { 'default': { 'ENGINE': 'django.db.back ...