zoukankan      html  css  js  c++  java
  • NOIP2017 逛公园 (Dijkstra)


    luogu P3953 逛公园##

      Time Limit: 10 Sec
      Memory Limit: 128 MB

    Description###

       策策同学特别喜欢逛公园。公园可以看成一张(N)个点(M)条边构成的有向图,且没有 自环和重边。其中1号点是公园的入口,(N)号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间。
       策策每天都会去逛公园,他总是从1号点进去,从(N)号点出来。
       策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间。如果1号点 到(N)号点的最短路长为(d),那么策策只会喜欢长度不超过(d + K)的路线。
       策策同学想知道总共有多少条满足条件的路线,你能帮帮它吗?
       为避免输出过大,答案对(P)取模。
       如果有无穷多条合法的路线,请输出(−1)
     

    Input###

       第一行包含一个整数 TT, 代表数据组数。
       接下来TT组数据,对于每组数据: 第一行包含四个整数 N,M,K,PN,M,K,P,每两个整数之间用一个空格隔开。
       接下来MM行,每行三个整数(a_i,b_i,c_i) ,代表编号为(a_i,b_i)的点之间有一条权值为 (c_i)的有向边,每两个整数之间用一个空格隔开。
     

    Output###

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

    Sample Input###

       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
     

    Sample Output###

      3
      -1

    HINT

    题目地址:luogu P3953 逛公园

    题目大意: 题目很简洁了:)

    题解:

      只是因为 Dijkstra 写挂了来粘一发
      **刷历年noip ing **


    AC代码

    // luogu-judger-enable-o2
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define pa pair<int,int>
    using namespace std;
    const int N=1e5+5,inf=1e9;
    int n,m,K,Mod;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    struct edge{
        int to,val,next;
    }e[N+N];
    int cnt_edge,last[N];
    inline void add_edge(int u,int v,int w){
        e[++cnt_edge]=(edge){v,w,last[u]};last[u]=cnt_edge;
    }
    inline int mo(int x){
        if(x>=Mod)return x-Mod;
        return x;
    }
    priority_queue<pa,vector<pa>,greater<pa> > q;
    int dis[N];
    bool vis[N];
    inline void dijkstra(){
        for(int i=1;i<=n;i++)dis[i]=inf;
        memset(vis,0,sizeof(vis));
        dis[1]=0;
        q.push(make_pair(0,1));
        while(!q.empty()){
            int u=q.top().second;q.pop();
            vis[u]=1;                                            //特别
            for(int i=last[u];i;i=e[i].next){
                int v=e[i].to;
                if(vis[v])continue;
                if(dis[v]>dis[u]+e[i].val){
                    dis[v]=dis[u]+e[i].val;
                    q.push(make_pair(dis[v],v));
                }
            }
        }
    }
    int f[N][55];
    bool ins[N][55];
    int dfs(int u,int d){
        int delta=d-dis[u];
        if(ins[u][delta])return -1;
        if(f[u][delta]!=-1)return f[u][delta];
        ins[u][delta]=1;
        if(u==n)f[u][delta]=1;
        else f[u][delta]=0;
        int res=0;
        for(int i=last[u];i;i=e[i].next){
            int v=e[i].to;
            if(d+e[i].val<=dis[v]+K){
                int val=dfs(v,d+e[i].val);
                if(val==-1)return f[u][delta]=-1;
                res=mo(res+val);
            }
        }
        ins[u][delta]=0;
        f[u][delta]=(f[u][delta]+res);
        return f[u][delta];
    }
    int main(){
        int Q=read();
        while(Q--){
            n=read(),m=read(),K=read(),Mod=read();
            cnt_edge=0;
            memset(last,0,sizeof(last));
            for(int i=1;i<=m;i++){
                int u=read(),v=read(),w=read();
                add_edge(u,v,w);
            }
            dijkstra();
            memset(ins,0,sizeof(ins));
            memset(f,-1,sizeof(f));
            printf("%d
    ",dfs(1,0));
        }
        return 0;
    }
    


      作者:skl_win
      出处:https://www.cnblogs.com/shaokele/
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Mysql安装
    Python的内存管理机制
    Ansible模块
    Redis持久化
    Linux——ansible(1)
    Flask
    Flask入门
    ajax处理回调函数,用ajax向后台发送数据
    数字类型钱币转换为大写
    ligerui多选动态下拉框
  • 原文地址:https://www.cnblogs.com/shaokele/p/9799533.html
Copyright © 2011-2022 走看看