zoukankan      html  css  js  c++  java
  • 洛谷3953 逛公园(DP)

    题面

    原题

    Solution

    这道题目看到k特别小,而且k×n的空间不会GG,那么我们考虑一个DP对吧。
    (dp[i][k])表示到了点i与最短路相差k值的方案数,然后直接记搜(不想用拓扑序列)就可以了。

    // luogu-judger-enable-o2
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define re register
    using namespace std;
    inline int gi(){
      int sum=0,f=1;char ch=getchar();
      while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
      while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
      return f*sum;
    }
    inline ll gl(){
      ll sum=0,f=1;char ch=getchar();
      while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
      while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
      return f*sum;
    }
    const int maxn=100010,maxm=200010,maxk=60;
    struct node{
      int to,nxt,w;
    }e[maxm],e1[maxm];
    int front[maxn],cnt1,cnt,front1[maxn],flag;
    void Addr(int u,int v,int w){
      e1[++cnt1]=(node){v,front1[u],w};front1[u]=cnt1;
    }
    void Add(int u,int v,int w){
      e[++cnt]=(node){v,front[u],w};front[u]=cnt;
    }
    typedef pair<int,int> pii;
    priority_queue<pii,vector<pii>,greater<pii> >q;
    int dis[maxn],vis[maxn];
    void spfa(int s){
      memset(dis,127,sizeof(dis));
      q.push(make_pair(0,s));dis[s]=0;
      memset(vis,0,sizeof(vis));
      while(!q.empty()){
        pii now=q.top();q.pop();int u=now.second;
        if(vis[u])continue;
        vis[u]=1;
        for(re int i=front1[u];i;i=e1[i].nxt){
          int v=e1[i].to;
          if(dis[v]>dis[u]+e1[i].w){
        dis[v]=dis[u]+e1[i].w;
        q.push(make_pair(dis[v],v));
          }
        }
      }
    }
    int n,m,K,p,Time;
    int Vis[maxn][maxk],dp[maxn][maxk];
    int dfs(int u,int k){
      if(Vis[u][k]==Time){flag=1;return 0;}
      if(dp[u][k]>0)return dp[u][k];
      Vis[u][k]=Time;int sum=0;
      for(re int i=front[u];i;i=e[i].nxt){
        int v=e[i].to,tmp=k-(dis[v]-dis[u]+e[i].w);
        if(tmp<0 || tmp>K)continue;
        sum=(sum+dfs(v,tmp))%p;
        if(flag)return 0;
      }
      Vis[u][k]=Time-1;
      if(u==n && k==0)return dp[u][k]=1;
      return dp[u][k]=sum;
    }
    int main(){
      int T=gi();
      while(T--){
        memset(front,0,sizeof(front));memset(front1,0,sizeof(front1));
        cnt=0,cnt1=0;memset(dp,-1,sizeof(dp));
        n=gi();m=gi();K=gi();p=gi();flag=0;
        for(re int i=1;i<=m;i++){
          int a=gi(),b=gi(),c=gi();
          Add(a,b,c);Addr(b,a,c);
        }
        spfa(n);int ans=0;
        for(re int i=0;i<=K;i++){
          Time++;
          ans=(ans+dfs(1,i))%p;
        }
        printf("%d
    ",!flag?ans:-1);
      }
      return 0;
    }
    
  • 相关阅读:
    Max Sum Plus Plus HDU
    Monkey and Banana HDU
    Ignatius and the Princess IV HDU
    Extended Traffic LightOJ
    Tram POJ
    Common Subsequence HDU
    最大连续子序列 HDU
    Max Sum HDU
    畅通工程再续
    River Hopscotch POJ
  • 原文地址:https://www.cnblogs.com/cjgjh/p/9813722.html
Copyright © 2011-2022 走看看