zoukankan      html  css  js  c++  java
  • 逛公园

    P3953 逛公园

    题意: 求(dis(1,n)<=MinDis(1,n)+K)的路径数

    用拓扑啊什么的一想就很麻烦。

    有一种玄学的做法:记忆化搜索

    (f[x][k])表示(dis(x,n)<=MinDis(x,n)+k)的路径数。

    先跑一般反向的最短路,然后dfs

    考虑边((x,y,w)),

    (ecause Mindis[x]-Mindis[y]+w<k​)

    ( herefore f[x][k]+=f[y][k-(Mindis[x]-Mindis[y]+w)])

    ( herefore f[x][k] = sum f[y][k-(Mindis[x]-Mindis[y]+w)])

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define Fur(i,x,y) for(int i=x;i<=y;i++)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define gc getchar
    int gi(){int x=0,f=0;char c=gc();while(c<'0'||'9'<c){if(c=='-')f=!f;c=gc();}while('0'<=c&&c<='9'){x=x*10+c-48;c=gc();}return f?(-x):x;}
    using namespace std;
    #define N 100010
    #define fl(head,i,x) for(int i=head[x],to;to=e[i].to,i;i=e[i].nxt)
    int n,m,cnt,k,mod,f[N][51],h1[N],h2[N],d[N];
    bool is[N][51],v[N];
    struct eg{int to,w,nxt;}e[N*4];
    void add(int x,int y,int w,int *head){e[++cnt]=(eg){y,w,head[x]};head[x]=cnt;}
    struct cmp{bool operator()(int a,int b){return d[a]>d[b];}};
    priority_queue<int,vector<int>,cmp>q;
    void spfa(){
        clr(d,126);
        int x;d[n]=0;q.push(n);
        while(!q.empty()){
            x=q.top();q.pop();v[x]=0;
            fl(h2,i,x)
            if(d[x]+e[i].w<d[to]){
                d[to]=d[x]+e[i].w;
                if(!v[to])q.push(to),v[to]=1;
            }
        }
    }
    int dfs(int x,int k){
        if(is[x][k])return -1;
        if(f[x][k])return f[x][k];
        is[x][k]=1;f[x][k]=(x==n);
        int tmp,w;
        fl(h1,i,x)
        if((tmp=d[to]-d[x]+e[i].w)<=k)
            if((w=dfs(to,k-tmp))){
                if(w==-1)return w;
                f[x][k]+=w;if(f[x][k]>mod)f[x][k]-=mod;
            }
        is[x][k]=0;
        return f[x][k];
    }
    int main(){
    int T=gi(),x,y,w;
    while(T--){
        n=gi();m=gi();k=gi();mod=gi();cnt=0;
        clr(f,0);clr(h1,0);clr(h2,0);clr(is,0);
        Fur(i,1,m)x=gi(),y=gi(),w=gi(),add(x,y,w,h1),add(y,x,w,h2);
        spfa();printf("%d
    ",dfs(1,k));
    }
    }
    
  • 相关阅读:
    太白老师 day06 编码 encode decode
    太白老师day6 1.代码块 2.is==id 3.小数据池
    MySQL 基本语法(1.表字段操作,2表记录管理 3.运算符管理4.SQL查询 5.约束6.索引
    List 接口常用子类及其特点
    Java 集合框架
    Java 常用工具类之基本对象包装类
    Java 常用工具类之 String 类
    Java 多线程间通信
    Java 多线程通信之多生产者/多消费者
    Java 之多线程通信(等待/唤醒)
  • 原文地址:https://www.cnblogs.com/mimiorz/p/10300411.html
Copyright © 2011-2022 走看看