DP+最短路

两遍最短路判零环

DP转移f[i][j] 到点i的距离比最短路多j时的方案数

 #include<bits/stdc++.h>
using namespace std;
const int N=;
struct node
{
    int to,nex,w;
}e[N],z[N];
int cnt,cnt1,head[],head2[];
int add(int x,int y,int w)
{
    e[++cnt1].to=y;e[cnt1].w=w;e[cnt1].nex=head[x];head[x]=cnt1;
    z[++cnt].to=x;z[cnt].w=w;z[cnt].nex=head2[y];head2[y]=cnt;
}
int f[][];
int d1[],d2[],d[],qq[N<<];
bool v[];int n,m,k,p;
void update(int &a,int b)
{
    a=(a+b)%p;
}
queue<int>q;
void work()
{
    scanf("%d%d%d%d",&n,&m,&k,&p);cnt=,cnt1=;
    memset(head,,sizeof(head));
    memset(head2,,sizeof(head2));
    for(int i=;i<=m;++i)
    {
        int x,y,w;
        scanf("%d%d%d",&x,&y,&w);
        add(x,y,w);
    }
    memset(v,,sizeof(v));memset(d1,0x3f,sizeof(d1));
    q.push();d1[]=;v[]=;
    while(!q.empty())
    {
        int x=q.front();q.pop();v[x]=;
        for(int i=head[x];i;i=e[i].nex)
        {
            int y=e[i].to;
            if(d1[y]>d1[x]+e[i].w)
            {
                d1[y]=d1[x]+e[i].w;
                if(!v[y])
                {
                    q.push(y);v[y]=;
                }
            }
        }
    }
    memset(v,,sizeof(v));memset(d2,0x3f,sizeof(d2));
    q.push(n);d2[n]=;v[n]=;
    while(!q.empty())
    {
        int x=q.front();q.pop();v[x]=;
        for(int i=head2[x];i;i=z[i].nex)
        {
            int y=z[i].to;
            if(d2[y]>d2[x]+z[i].w)
            {
                d2[y]=d2[x]+z[i].w;
                if(!v[y])
                {
                    q.push(y);v[y]=;
                }
            }
        }
    }
   
    int top=;memset(d,,sizeof(d));
    for(int i=;i<=n;++i)
    for(int j=head[i];j;j=e[j].nex)
    {
        if(d1[i]+e[j].w==d1[e[j].to])d[e[j].to]++;
    }
    for(int i=;i<=n;++i)if(!d[i])qq[++top]=i;
    for(int i=;i<=top;++i)
    {
        int x=qq[i];
        for(int j=head[x];j;j=e[j].nex)
        if(d1[x]+e[j].w==d1[e[j].to])
        {
            int y=e[j].to;
            d[y]--;
            if(d[y]==)qq[++top]=y;
        }
    }
    for(int i=;i<=n;++i)
    if(d[i]&&d1[i]+d2[i]<=d1[n]+k)
    {
        puts("-1");return;
    }
    int ans=;
    memset(f,,sizeof(f));
    f[][]=;
    for(int i=;i<=k;++i)
    {
        for(int j=;j<=top;++j)
        for(int u=head[qq[j]];u;u=e[u].nex)
        {
            if(d1[qq[j]]+e[u].w==d1[e[u].to])
            update(f[e[u].to][i],f[qq[j]][i]);
        }
       
        for(int j=;j<=n;++j)
        for(int u=head[j];u;u=e[u].nex)
        {
            if(d1[j]+e[u].w!=d1[e[u].to]&&i+d1[j]-d1[e[u].to]+e[u].w<=k)
            update(f[e[u].to][i+d1[j]-d1[e[u].to]+e[u].w],f[j][i]);
        }
    }
    for(int i=;i<=k;++i)
    update(ans,f[n][i]);
    printf("%d\n",ans);
    return ;
}
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        work();
    }
    return ;
}

NOIP2017 D1T3逛公园的更多相关文章

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

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

  2. NOIP2017 D1T3 逛公园

    发现 \(K\) 很小,不妨设置一个 \(O(NK)\) 的 \(DP\). 发现可行的最短路必须满足是 \(d <= dis <= d + K\). 由逆向思维,则是从某点出发,可以消耗 ...

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

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

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

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

  5. NOIP2017:逛公园

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

  6. 【NOIP2017】逛公园 最短路+DP

    诶,去年场上不会处理$0$的环,只拿了$60$有点可惜. 我们先不管边边权为$0$的边. 我们先跑一次最短路,令$dis[u]$表示从$1$至$u$的最短路的长度. 那么根据题目的要求,从起点走到$u ...

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

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

  8. 【NOIP2017】逛公园 D1 T3

    记忆化搜索 跑一次反向的最短路求出MinDis(u,n)MinDis(u,n)MinDis(u,n) f[u][k]f[u][k]f[u][k]表示dis(u,n)<=MinDis(u,n)+d ...

  9. 【LOJ2316】「NOIP2017」逛公园

    [题目链接] [点击打开链接] [题目概括] 对给定\(K\),起点\(1\)到终点\(n\)中对长度为\([L,L+K]\)的路径计数. \(L\)为\(1\)到\(n\)的最短路长度. [思路要点 ...

随机推荐

  1. wepy开发小程序 大坑....本地调试ok,小程序上传体验版 组件出现问题

    如果你碰到的上述问题(本地调试ok,小程序上传体验版 各种莫名其妙的问题-卡死-组件属性失效-$apply()不起作用) 您需要关闭 微信开发者工具中: 1.微信开发者工具-->项目--> ...

  2. NYOJ 141 Squares (数学)

    题目链接 描述 A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degre ...

  3. BeanPostProcessor的五大接口

    BeanPostProcessor 关于对象初始化前后的回调. public interface BeanPostProcessor { //该方法在bean实例化完毕(且已经注入完毕),在after ...

  4. 14 - 函数参数检测-inspect模块

    目录 1 python类型注解 2 函数定义的弊端 3 函数文档 4 函数注解 4.1 annotation属性 5 inspect模块 5.1 常用方法 5.2 signature类 5.3 par ...

  5. Window文本在Linux中出现的^M问题

    问题:在Windows中写了一个shell脚本在Linux中死活不能运行,怎么也查不出错误,原来是格式问题. 原因:Windows/DOS系统的换行符是/r/n,Unix/Linux系统的换行符是/n ...

  6. windows 10开启bash on windows,配置sshd,部署hadoop

    1.安装Bash on Windows 这个参考官网步骤,很容易安装,https://msdn.microsoft.com/en-us/commandline/wsl/install_guide 安装 ...

  7. 对cgic的理解——name选项

    #include <stdio.h>#include <stdlib.h>#include <string.h>#include "cgic.h" ...

  8. Python+Selenium 自动化实现实例-数据驱动实例

    #coding=utf-8 from selenium import webdriver driver = webdriver.Firefox() driver.implicitly_wait(10) ...

  9. fiddler添加监测请求的 ip地址

    本文转载自:http://www.jackness.org/2014/12/26/%E7%BB%99fiddler%E6%B7%BB%E5%8A%A0%E7%9B%91%E6%B5%8B%E8%AF% ...

  10. bootstrap navbar items alignment

    https://stackoverflow.com/questions/19733447/bootstrap-navbar-with-left-center-or-right-aligned-item ...