zoukankan      html  css  js  c++  java
  • [NOIP2017]逛公园

    建一个反图跑个最短路,然后记忆化搜索一下。
    (很迷的是堆优化dij就wa了,线段树优化的和spfa就A了。)(求dalao看看我的堆优化dij是不是打错了,但是过了80分)。
    spfa的AC代码:

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <cctype>
    #include <cstring>
    using namespace std;
    const int N=100005;
    int T,n,m,K,p,ecnt,head[N],dis[N],fhead[N];
    bool vis[N];
    long long f[N][51];
    bool inq[N][51];
    struct Edge{int to,nxt,val;}e[N<<2];
    void add(int bg,int ed,int val){e[++ecnt].nxt=head[bg];e[ecnt].to=ed;e[ecnt].val=val;head[bg]=ecnt;}
    void add2(int bg,int ed,int val){e[++ecnt].nxt=fhead[bg];e[ecnt].to=ed;e[ecnt].val=val;fhead[bg]=ecnt;}
    int rd() {
      int x=0,f=1;char ch=getchar();
      while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
      while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
      return x*f;
    }
    struct Node{bool operator ()(int x,int y) {return dis[x]>dis[y];}};
    void dij(){
      priority_queue<int,vector<int>,Node>q;
      memset(dis,0x3f,sizeof dis);
      memset(vis,0,sizeof vis);
      q.push(n);
      dis[n]=0;
      while(!q.empty()) {
        int u=q.top();q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=fhead[u];i;i=e[i].nxt) {
          int v=e[i].to;
          dis[v]=min(dis[v],dis[u]+e[i].val);
          q.push(v);
        }
      }
    }
    long long dp(int x,int k) {
      if(inq[x][k]) return -1;
      if(f[x][k]) return f[x][k];
      inq[x][k]=1;if(x==n) f[x][k]=1;else f[x][k]=0;
      for(int i=head[x];i;i=e[i].nxt) {
        int v=e[i].to;
        int tmp=dis[v]-dis[x]+e[i].val;
        if(tmp<=k) {
          int tp=dp(v,k-tmp);
          if(tp==-1) return f[x][k]=-1;
          f[x][k]=(f[x][k]+tp)%p;
        }
      }
      inq[x][k]=0;
      return f[x][k];
    }
    void spfa() {
      memset(dis,0x3f,sizeof dis);
      queue<int>q;
      q.push(n);
      vis[n]=1;dis[n]=0;
      while(!q.empty()) {
        int u=q.front();vis[u]=0;q.pop();
        for(int i=fhead[u];i;i=e[i].nxt) {
          int v=e[i].to;
          if(dis[u]+e[i].val<dis[v]) {
            dis[v]=dis[u]+e[i].val;
            if(!vis[v]) q.push(v),vis[v]=1;
          }
        }
      }
    }
    int main() {
      T=rd();
      while (T--) {
        memset(f,0,sizeof f);memset(inq,0,sizeof inq);memset(head,0,sizeof head);memset(fhead,0,sizeof fhead);ecnt=0;
        n=rd();m=rd();K=rd();p=rd();
        for(int i=1,a,b,c;i<=m;i++)
           a=rd(),b=rd(),c=rd(),add(a,b,c),add2(b,a,c);
        spfa();
        long long ans=dp(1,K);
        printf("%lld
    ",ans);
      }
    }
    

    堆优化的:

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <cctype>
    #include <cstring>
    using namespace std;
    const int N=100005;
    int T,n,m,K,p,ecnt,head[N],dis[N],fhead[N];
    bool vis[N];
    long long f[N][51];
    bool inq[N][51];
    struct Edge{int to,nxt,val;}e[N<<2];
    void add(int bg,int ed,int val){e[++ecnt].nxt=head[bg];e[ecnt].to=ed;e[ecnt].val=val;head[bg]=ecnt;}
    void add2(int bg,int ed,int val){e[++ecnt].nxt=fhead[bg];e[ecnt].to=ed;e[ecnt].val=val;fhead[bg]=ecnt;}
    int rd() {
      int x=0,f=1;char ch=getchar();
      while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
      while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
      return x*f;
    }
    struct Node{bool operator ()(int x,int y) {return dis[x]>dis[y];}};
    void dij(){
      priority_queue<int,vector<int>,Node>q;
      memset(dis,0x3f,sizeof dis);
      memset(vis,0,sizeof vis);
      q.push(n);
      dis[n]=0;
      while(!q.empty()) {
        int u=q.top();q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=fhead[u];i;i=e[i].nxt) {
          int v=e[i].to;
          if(dis[u]+e[i].val>dis[v]) continue;
            dis[v]=min(dis[v],dis[u]+e[i].val);
          q.push(v);
        }
      }
    }
    long long dp(int x,int k) {
      if(inq[x][k]) return -1;
      if(f[x][k]) return f[x][k];
      inq[x][k]=1;if(x==n) f[x][k]=1;else f[x][k]=0;
      for(int i=head[x];i;i=e[i].nxt) {
        int v=e[i].to;
        int tmp=dis[v]-dis[x]+e[i].val;
        if(tmp<=k) {
          int tp=dp(v,k-tmp);
          if(tp==-1) return f[x][k]=-1;
          f[x][k]=(f[x][k]+tp)%p;
        }
      }
      inq[x][k]=0;
      return f[x][k];
    }
    int main() {
      T=rd();
      while (T--) {
        memset(f,0,sizeof f);memset(inq,0,sizeof inq);memset(head,0,sizeof head);memset(fhead,0,sizeof fhead);ecnt=0;
        n=rd();m=rd();K=rd();p=rd();
        for(int i=1,a,b,c;i<=m;i++)
           a=rd(),b=rd(),c=rd(),add(a,b,c),add2(b,a,c);
        dij();
        long long ans=dp(1,K);
        printf("%lld
    ",ans);
      }
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    性能优化方法
    awk命令
    jvm 性能调优工具之 jmap
    linux下tomcat 8的安装以及tomcat启动慢问题
    解析Java中的String、StringBuilder、StringBuffer类(一)
    JDBC详解系列(四)之建立Stament和执行SQL语句
    JDBC详解系列(三)之建立连接(DriverManager.getConnection)
    Paho -物联网 MQTT C Cient的实现和详解
    Paho
    Subscription wildcards(MQTT)
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9359218.html
Copyright © 2011-2022 走看看