题目链接

problem

一个有向无重边自环图,设\(D\)为从\(1\)号点走到\(n\)号点的最短距离。问有多少条从\(1\)到\(n\)的路径长度不超过\(D+K\)。\(K\)为给定的值,且\(K\le 50\)

如果有无数条,输出-1

solution

下面有\(dis[i]\)表示\(i\)号点到\(n\)号点的最短路径长度。

设\(f[i][j]\)表示从\(i\)号点走到\(n\)号点,走了\(j\)的多余路径的方案数。就有如下转移:

\[f[i][j]=\sum\limits_{i,v之间有边}f[v][j-(dis[v]+w-dis[i])]
\]

记忆化搜索即可。

注意到如果出现了无数条路径,肯定出现了0环。也就是某一个状态被访问了两次。记忆化搜索的过程中标记一下即可。

code

#include<cstdio>
#include<iostream>
#include<ctime>
#include<queue>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
const int N = 200010;
ll read() {
ll x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
struct node {
int v,nxt,w;
}e[N << 1],E[N << 1];
int head[N],ejs;
void add(int u,int v,int w) {
e[++ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;e[ejs].w = w;
}
int head2[N],ejs2;
void add2(int u,int v,int w) {
E[++ejs2].v = v;E[ejs2].w = w;E[ejs2].nxt = head2[u];head2[u] = ejs2;
}
queue<int>q;
int n,m,K,mod,dis[N],vis[N];
void spfa(int U) {
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[U] = 0;
q.push(U);
while(!q.empty()) {
int u = q.front();q.pop();vis[u] = 0;
for(int i = head2[u];i;i = E[i].nxt) {
int v = E[i].v;
if(dis[v] > dis[u] + E[i].w) {
dis[v] = dis[u] + E[i].w;
if(!vis[v]) {
vis[v] = 1;q.push(v);
}
}
}
}
}
int bz[N][60],f[N][60];
int dfs(int u,int x) {
if(bz[u][x] == 2) return f[u][x];
if(bz[u][x] == 1) return -1;
bz[u][x] = 1;
for(int i = head[u];i;i = e[i].nxt) {
int v = e[i].v;
int w = x - (dis[v] + e[i].w - dis[u]);
if(w < 0 || w > K) continue;
int k = dfs(v,w);
if(k == -1) return -1;
f[u][x] += k;
f[u][x] %= mod;
}
bz[u][x] = 2;
return f[u][x];
}
int main() {
int T = read();
while(T--) {
memset(head,0,sizeof(head));
ejs2 = 0;
memset(head2,0,sizeof(head2));
ejs = 0;
n = read(),m = read(),K = read(),mod = read(); memset(f,0,sizeof(f));
memset(bz,0,sizeof(bz)); for(int i = 1;i <= m;++i) {
int u = read(),v = read(),w = read();
add(u,v,w);
add2(v,u,w);
} spfa(n); f[n][0] = 1;
int ans = 0;
for(int i = 0;i <= K;++i) {
int k = dfs(1,i);
if(k == -1) {
ans = -1;break;
}
ans += k;
ans %= mod;
}
printf("%d\n",ans);
} return 0;
}

Noip2017Day1T3 逛公园的更多相关文章

  1. [vijos P1083] 小白逛公园

    不知怎地竟有种错觉此题最近做过= =目测是类似的?那道题貌似是纯动归? 本来今晚想做两道题的,一道是本题,一道是P1653疯狂的方格取数或NOI08 Employee,看看现在的时间目测这个目标又达不 ...

  2. Bzoj 1756: Vijos1083 小白逛公园 线段树

    1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1021  Solved: 326[Submit][Statu ...

  3. BZOJ 1756: Vijos1083 小白逛公园

    题目 1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 856  Solved: 264[Submit][Sta ...

  4. JDOJ-P1260 VIJOS-P1083 小白逛公园

    首先,在这里给大家推荐一个网站,https://neooj.com:8082,这是我母校的网站 言归正传,题目描述 VIJOS-P1083 小白逛公园 Time Limit: 1 Sec  Memor ...

  5. [NOIP2017] 逛公园

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

  6. [NOIp 2017]逛公园

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

  7. 【NOIP 2017】逛公园

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

  8. 逛公园 [NOIP2017 D1T3] [记忆化搜索]

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

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

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

随机推荐

  1. 数据存储与访问之——SharedPreferences

    使用SharedPreferences(保存用户偏好参数)保存数据, 当我们的应用想要保存用户的一些偏好参数,比如是否自动登陆,是否记住账号密码,是否在Wifi下才能 联网等相关信息,如果使用数据库的 ...

  2. Redis & memcached PK

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

  3. DSP编程与调试总结

    (1)error: can't allocate .ebss, size 000c450d (page 1) in DXINTFRAM2 (avail: 00010000) error: errors ...

  4. 微服务与K8S容器云平台架构

    微服务与K8S容器云平台架构 微服务与12要素 网络 日志收集 服务网关 服务注册 服务治理- java agent 监控 今天先到这儿,希望对技术领导力, 企业管理,系统架构设计与评估,团队管理, ...

  5. 编辑器之神vim的一些常用快捷键整理

    yy:复制 光标所在的这一行 4yy:复制 光标所在行开始向下的4行 p:粘贴 dd:剪切(删除) 光标所在的这一行 4dd:剪切(删除) 光标所在行向下的4行 D:从当前的光标开始向后剪切,一直到行 ...

  6. 【搬了一套别人的cf】

    自己打了一堆没保存瞬间全没了.... 没有继续写的欲望 https://www.cnblogs.com/tea-egg/p/11664350.html

  7. [译]Vulkan教程(09)窗口表面

    [译]Vulkan教程(09)窗口表面 Since Vulkan is a platform agnostic API, it can not interface directly with the ...

  8. 转载-C语言中<<、>>、&、|的实际用途

    C语言中<<.>>.&.|的实际用途 作为一个开发人员,在看别人项目或者看第三方库的源代码时,可能经常会看到譬如a>>4&0x0f这样的写法,对于一 ...

  9. 基于python的yaml配置文件使用方法

    一.介绍 YAML是一种简洁的非标记语言 YAML以数据为中心,使用空白.缩进.分行组织数据,从而使表达更加简洁易懂 二.基本规则 大小写敏感 使用缩进表示层级关系 禁止使用Tab缩进,只能使用空格键 ...

  10. SimpleDateFormat类简单学习

    一.简介 SimpleDateFormat是一个格式化和解析日期的具体类,其可以将时间转化为指定格式的日期字符串,也可以将具有格式的日期字符串转换为时间. formatting (date → tex ...