【题目链接】

【题目概括】

对给定\(K\),起点\(1\)到终点\(n\)中对长度为\([L,L+K]\)的路径计数。

\(L\)为\(1\)到\(n\)的最短路长度。

【思路要点】

  • 考虑\(DP\),定义\(dp[i][j]\)表示从\(i\)点到终点\(n\)的距离比原来的最短距离长了\(j\)的方案数。
  • 那么考虑转移,\(dp[u][j]=\sum dp[v][j-g]\),其中\(g=dis[v]+w(i,j)-dis[u]\)。

【代码】

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

using namespace std;

const int N = 2e5 + 5;

struct _edge {
    int to, nt, w;
} E1[N], E2[N];

int H1[N], H2[N], dis[N];
int edgeCnt1, edgeCnt2;
bool vis[N];
bool ban[N][55];
int dp[N][55];
int n, m, k, MOD;

void addEdge1(int u, int v, int w) {
    E1[++edgeCnt1] = (_edge){v, H1[u], w};
    H1[u] = edgeCnt1;
}

void addEdge2(int u, int v, int w) {
    E2[++edgeCnt2] = (_edge){v, H2[u], w};
    H2[u] = edgeCnt2;
}

void init() {
    edgeCnt1 = edgeCnt2 = 0;
    for (int i = 1; i <= n; i++)
        H1[i] = H2[i] = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 0; j <= k; j++)
            dp[i][j] = -1, ban[i][j] = 0;
}

void spfa(int s) {
    for (int i = 1; i <= n; i++)
        dis[i] = inf, vis[i] = 0;
    queue<int> q;
    q.push(s);
    vis[s] = 1;
    dis[s] = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for (int e = H2[u]; e; e = E2[e].nt) {
            int v = E2[e].to;
            if (dis[v] > dis[u] + E2[e].w) {
                dis[v] = dis[u] + E2[e].w;
                if (!vis[v]) {
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
}

int dfs(int u, int k) {
    if (k < 0)
        return 0;
    else if (ban[u][k])
        return -1;
    else if (dp[u][k] != -1)
        return dp[u][k];
    ban[u][k] = 1;
    dp[u][k] = 0;
    if (u == n)
        dp[u][k]++;
    for (int e = H1[u]; e; e = E1[e].nt) {
        int v = E1[e].to;
        if (dis[v] == inf)
            continue;
        int g = dis[v] + E1[e].w - dis[u];
        int res = dfs(v, k - g);
        if (res == -1)
            return -1;
        dp[u][k] = (dp[u][k] + res) % MOD;
    }
    ban[u][k] = 0;
    return dp[u][k];
}

int main() {
    int T; scanf("%d", &T);
    while (T--) {
        scanf("%d %d %d %d", &n, &m, &k, &MOD);
        init();
        for (int i = 1; i <= m; i++) {
            int u, v, w; scanf("%d %d %d", &u, &v, &w);
            addEdge1(u, v, w), addEdge2(v, u, w);
        }
        spfa(n);
        int ans = dfs(1, k);
        printf("%d\n", ans);
    }
    return 0;
}

【LOJ2316】「NOIP2017」逛公园的更多相关文章

  1. LOJ2316. 「NOIP2017」逛公园【DP】【最短路】【思维】

    LINK 思路 因为我想到的根本不是网上的普遍做法 所以常数出奇的大,而且做法极其暴力 可以形容是带优化的大模拟 进入正题: 首先一个很显然的思路是如果在合法的路径网络里面存在零环是有无数组解的 然后 ...

  2. 「NOIP2017」逛公园

    传送门 Luogu 解题思路 考虑 \(\text{DP}\). 设 \(f[u][k]\) 表示从 \(u\) 到 \(n\) 走过不超过 \(Mindis(u, n) + k\) 距离的方案数. ...

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

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

  4. 「WC2013」糖果公园

    「WC2013」糖果公园 传送门 树上带修莫队板子题. 看懂题意后就是板子题了. 参考代码: #include <algorithm> #include <cstdio> #i ...

  5. 「NOIP2017」宝藏

    「NOIP2017」宝藏 题解 博客阅读效果更佳 又到了一年一度NOIPCSP-S 赛前复习做真题的时间 于是就遇上了这道题 首先观察数据范围 \(1 \le n \le 12\) ,那么极大可能性是 ...

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

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

  7. 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索

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

  8. 【NOIP2017】逛公园(最短路图,拓扑排序,计数DP)

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

  9. NOIP2017:逛公园

    Sol 发现\(NOIP2017\)还没\(AK\)??? 赶紧改 考场上明明打出了\(DP\),没时间了,没判环,重点是没初始化数组,爆\(0\) \(TAT\) 先最短路,然后\(f[i][j]\ ...

随机推荐

  1. [转帖]Windows 下如何配置Oracle ASM???

    Windows 下如何配置Oracle ASM??? candon123关注10人评论16725人阅读2011-02-09 21:40:57   本篇介绍了如何在windows下创建裸设备,并创建AS ...

  2. L2-013. 红色警报(并查集+无向图联通分量)

    战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不 ...

  3. Bash Plays with Functions CodeForces - 757E (积性函数dp)

    大意: 定义函数$f_r(n)$, $f_0(n)$为pq=n且gcd(p,q)=1的有序对(p,q)个数. $r \ge 1$时, $f_r(n)=\sum\limits_{uv=n}\frac{f ...

  4. sql server isnull函数

    isnull函数 --ISNULL() 函数用于规定如何处理 NULL 值 语法:SELECT ISNULL(check_expression, replacement_value) --check_ ...

  5. 第二章 单表查询 T-SQL语言基础(1)

    单表查询(1) 本章:逻辑查询处理,特定的SELECT查询生成正确的结果集而要经历的一系列逻辑阶段;单表查询的其他方面,包括:运算符,空值(NULL),字符的处理和临时数据,分级(ranking),C ...

  6. Kong/Konga - Docker容器化安装

    1.0 安装kong + postgresDB docker network create kong-net docker pull postgres:latest docker run -d --n ...

  7. execjs执行js代码报错:Exception in thread Thread-1

    最近在爬一个js数据加密的网站的时候,出了点问题,困扰了我两天 直接运行js文件的时候正常,但是用execjs运行js代码的时候总是会报错 最后翻了很多博客之后,终于找到了原因:原因是有一个程序在使用 ...

  8. openlayers之天地图为底图 叠加其他底图 加载遇到的各种报错

    今天以前使用天地图为底图时,map里source的定义:http://t3.tianditu.com~~~ 今天突然报跨域的错误,原有地址访问受限,可是key值是有的 最后发现就是前半段的原因 将前半 ...

  9. java常用的加密技术

    详见:https://blog.csdn.net/it_beecoder/article/details/71480770 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以 ...

  10. 升级python导致yum报错的解决方法

    把python从2.7升级到3.6后 , 使用yum报错 File ‘’/usr/bin/yum'', line 30 except KeyboardInterrupt, e: ^ 故障原因:yum采 ...