题目链接

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. react-router刷新页面Cannot GET 问题

    最近在做项目的时候遇到了如下错误 并在控制台看到了如下的报错 我先是按照控制台的错误搜索,得出的结果都是对meta头部进行设置,允许资源请求,但是问题依然没有解决,偶然间改变了想法,会不会是路由的问题 ...

  2. Mac环境安装非APP STORE中下载的软件,运行报错:“XXX” is damaged and can’t be opened. You should move it to the Trash. 解决办法

    出现这个错误的大多数原因都是因为系统设置的问题,因为系统不信任你从其他地方下载的软件安装包,所以运行时就给你阻止了.具体的设置步骤如下: 1. 打开系统偏好设置 (System Preferences ...

  3. jq实现回车键事件

    我们写系统的时候常常因为要点击显得很麻烦,习惯了回车键完成一些东西. 接下来就直接上代码吧.jq实现回车键事件 keyDowm: () => { $("body").keyd ...

  4. linux 执行 javac 报错 javac: command not found

    bash: javac: command not found java 版本 1.8 [root@localhost home]# java -version openjdk version &quo ...

  5. 关于thymeleaf中th:if的使用

    运用于判断表达式中时,关系判断使用 gt / ge / eq / lt / le / ne (即:使用缩写) gt: great than(大于)> ge: great equal(大于等于)& ...

  6. maven与gradle的阿里云仓库配置

    直接参考 https://help.aliyun.com/document_detail/102512.html 就好. 阿里云maven仓库官网 https://maven.aliyun.com/m ...

  7. C#的语法----程序结构(2)

    接下来我们继续学习程序流程控制的语法! switch-case 用来处理多条件的定值的判断. 语法: switch(变量或者表达式的值) { case value1:要执行的代码1: break; c ...

  8. 关于css里决定样式优先级的权重

    最近学css样式,优先级有点繁琐,简单记录一下. css中的优先级规则为: 有!important的最优先: 其次权重高的优先: 权重相同则后定义优先,会覆盖前面的. 至于权重: #id 为100: ...

  9. angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题

     壹 ❀ 引 angularjs除了惊为天人的双向数据绑定外,路由也是出彩的一笔,通过路由配置,我们能在不发起页面跳转的情况下,对当前页内容进行整体更新,angularjs提供了ngRoute模块用于 ...

  10. java大数习题

    大数加法,题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 import java.math.BigInteger; import java.ut ...