P3953 NOIP2017 d1t3 逛公园

题目描述

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

策策每天都会去逛公园,他总是从1号点进去,从NN 号点出来。

策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间。如果1号点 到NN 号点的最短路长为dd ,那么策策只会喜欢长度不超过d + Kd+K 的路线。

策策同学想知道总共有多少条满足条件的路线,你能帮帮它吗?

为避免输出过大,答案对PP 取模。

如果有无穷多条合法的路线,请输出−1。

输入输出格式

输入格式:

第一行包含一个整数 TT , 代表数据组数。

接下来TT 组数据,对于每组数据: 第一行包含四个整数 N,M,K,PN,M,K,P ,每两个整数之间用一个空格隔开。

接下来MM 行,每行三个整数a_i,b_i,c_iai?,bi?,ci? ,代表编号为a_i,b_iai?,bi? 的点之间有一条权值为 c_ici? 的有向边,每两个整数之间用一个空格隔开。

输出格式:

输出文件包含 TT 行,每行一个整数代表答案。

输入输出样例

输入样例#1: 复制

2
5 7 2 10
1 2 1
2 4 0
4 5 2
2 3 2
3 4 1
3 5 2
1 5 3
2 2 0 10
1 2 0
2 1 0

输出样例#1: 复制

3
-1

说明

【样例解释1】

对于第一组数据,最短路为 3。 1 – 5, 1 – 2 – 4 – 5, 1 – 2 – 3 – 5 为 3 条合法路径。

【测试数据与约定】

对于不同的测试点,我们约定各种参数的规模不会超过如下

测试点编号   TT     NN     MM     KK     是否有0边
1 5 5 10 0
2 5 1000 2000 0
3 5 1000 2000 50
4 5 1000 2000 50
5 5 1000 2000 50
6 5 1000 2000 50
7 5 100000 200000 0
8 3 100000 200000 50
9 3 100000 200000 50
10 3 100000 200000 50

对于 100%的数据, 1 \le P \le 10^9,1 \le a_i,b_i \le N ,0 \le c_i \le 10001≤P≤109,1≤ai?,bi?≤N,0≤ci?≤1000 。

数据保证:至少存在一条合法的路线。

只有60的记忆化搜索。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<complex>
#include<queue>
#define N    100000+5
#define K    50+3
#define INF  0x7FFFFFFF
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
     while(s>‘9‘ || s<‘0‘){if(s==‘-‘)f=-1;s=getchar();}
     while(s<=‘9‘ && s>=‘0‘){x=x*10+s-‘0‘;s=getchar();}
     return x*f;
}
struct edge{int to,next,v;}a[N],re[N];
int n,m,k,p,cnt,cnt1,head[N],headre[N],v[N],ans[N][K],vis[N][K],d[N],alive[N];
void add(int x,int y,int v)
{
    a[++cnt].to=y;a[cnt].v=v;
    a[cnt].next=head[x];head[x]=cnt;
}
void addre(int x,int y,int v)
{
    re[++cnt1].to=y;re[cnt1].v=v;
    re[cnt1].next=headre[x];headre[x]=cnt1;
}

int dfs(int x,int b)
{
    if(b<0)return 0;
    if(vis[x][b]==1)return -INF;
    if(ans[x][b]!=-1)return ans[x][b];
    vis[x][b]=1;
    int key=0;
    if(x==n)key++;
    for(int i=head[x];i;i=a[i].next)
        if(alive[a[i].to])
        {
            int v=a[i].to;
            int delta=a[i].v-(d[v]-d[x]);
            int w=dfs(v,b-delta);
            if(w==-INF)return -INF;
            else key=(key+w)%p;
        }
    ans[x][b]=key%p;
    vis[x][b]=0;
    return key;
}

void spfa()
{
    queue<int>q;
    q.push(1);v[1]=1;
    d[1]=0;
    while(!q.empty())
    {
        int h=q.front();q.pop();v[h]=0;
        for(int i=head[h];i;i=a[i].next)
        {
            int x=a[i].to;
            if(d[h]+a[i].v<d[x])
            {
                d[x]=d[h]+a[i].v;
                if(!v[h])
                q.push(x);
            }
        }
    }
}
void da()
{
    queue<int>q;
    q.push(n);alive[n]=1;
    while(!q.empty())
    {
        int h=q.front();q.pop();
        for(int i=headre[h];i;i=re[i].next)
        {
            int x=re[i].to;
            if(!alive[x]){alive[x]=1;q.push(x);}
        }
    }
}
void init()
{
    for(int i=1;i<=n;i++)
    {
        a[i].to=a[i].next=a[i].v=0;
        re[i].to=re[i].next=re[i].v=0;
        head[i]=headre[i]=v[i]=d[i]=alive[i]=0;
        for(int l=0;l<=k;l++)
        {
            ans[i][l]=-1;
            vis[i][l]=0;
        }
    }
}
int main()
{
    int t;t=read();
    while(t--)
    {
        n=read(),m=read(),k=read(),p=read();
        init();
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            a=read(),b=read(),c=read();
            add(a,b,c);addre(b,a,c);
        }
        for(int i=1;i<=n;i++)d[i]=INF;
        spfa();
        da();

        //for(int i=1;i<=n;i++)cout<<d[i]<<‘ ‘;

        int z=dfs(1,k);
        if(z==-INF)printf("-1\n");else printf("%d\n",z%p);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/fdfzhyf/p/8711127.html

时间: 2024-11-05 22:57:46

P3953 NOIP2017 d1t3 逛公园的相关文章

Luogu P3953【NOIP2017】逛公园【最短路+拓扑排序+动态规划】

题目描述 策策同学特别喜欢逛公园.公园可以看成一张NN个点MM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,NN号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会去逛公园,他总是从1号点进去,从NN号点出来. 策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间.如果1号点 到NN号点的最短路长为dd,那么策策只会喜欢长度不超过d + Kd+K的路线. 策策

luogu 3953 逛公园

noip2017 D1T3 逛公园 某zz选手看到数据范围直接就最短路计数了,结果写错了爆零 题目大意: N个点M条边构成的有向图,且没有自环和重边.其中1号点是起点,N号点是公园的终点,每条边有一个非负权值, 代表经过这条边所要花的时间 如果1号点到N号点的最短路长为d,那么策策只选择长度不超过d + K的路线 求总共有多少条满足条件的路线 为避免输出过大,答案对P取模. 如果有无穷多条合法的路线,请输出?1 思路: 首先需要求出最短路用spfa 然后我们dfs的时候dp 具体见注释 1 #i

Luogu P3953 逛公园(最短路+记忆化搜索)

P3953 逛公园 题面 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园的入口,\(N\) 号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会去逛公园,他总是从 \(1\) 号点进去,从 \(N\) 号点出来. 策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间.如果 \(

【比赛】NOIP2017 逛公园

考试的时候灵光一闪,瞬间推出DP方程,但是不知道怎么判-1,然后?然后就炸了. 后来发现,我只要把拓扑和DP分开,中间加一个判断,就AC了,可惜. 看这道题,我们首先来想有哪些情况是-1:只要有零环在满足题目要求的路径上,那么这条路径就可以不停地走,于是就-1了. 如何判有没有零环呢? 机械化地两遍不同方向的SPFA,就知道某个点在不在最短路上,以此建一个最短路图,在最短路图上找零环.于是就拓扑啦.稍加判断就解决了整个题目最关键的-1. 接下来就是DP了,设f[i][j]表示走到i点,走过路程已

[NOIP2017] 逛公园

[NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^5\) 题目解法 两个月后再看也不是太难,自己就能独立思考出来. 首先是判-1的问题,显然能产生-1的只有0环. 所以把0环都找出来, 然后检查一下\(dis[\)\(1\),环\(]\) + \(dis[\)环,\(n]\) 是否小于等于 \(dis[1,n]+K\)即可. 如果不是无限路径的话,

[Luogu P3953] 逛公园 (最短路+拓扑排序+DP)

题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易可以想到一个做法,就是魔改迪杰斯特拉做法: 如果一个点可以更新到达其他点的距离,那个点的方案数就是这个点的方案数:如果一个点所更新出来的距离和之前的相等,那个点的方案数加等当前点的方案数. 用式子可以表现为: f[j]=f[i] (dis[j]>dis[i]+x)   f[j]+=f[i] (dis

P3953 逛公园

Description 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会去逛公园,他总是从1号点进去,从N号点出来. 策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间.如果1号点 到NN号点的最短路长为dd,那么策策只会喜欢长度不超过d+K的路线. 策策同学

洛谷3953:逛公园——题解

https://www.luogu.org/problemnew/show/P3953 策策同学特别喜欢逛公园.公园可以看成一张n个点m条边构成的有向图,且没有自环和重边.其中1号点是公园的入口,n号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花的时间. 策策每天都会去逛公园,他总是从1号点进去,从n号点出来. 策策喜欢新鲜的事物,他不希望有两天逛公园的路线完全一样,同时策策还是一个特别热爱学习的好孩子,他不希望每天在逛公园这件事上花费太多的时间.如果1号点到n号点的最短路长为d

TYVJ1427 小白逛公园

P1427 小白逛公园 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了.    一开始,小白就根据公园的风景给每个公园打了分-.-.小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第a个和第b个公园之间(包括a.b两个公园)选择连续的一些公园玩.小白当然希望选出的公园的分数总和尽量高咯