zoukankan      html  css  js  c++  java
  • [luogu3952 noip2017] 逛公园 (计数dp+最短路)

    传送门

    Description

    Input

    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

    【样例解释1】

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

    【测试数据与约定】

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

    Solution

    设dis[i]为i到n最短路
    设dp[i][j]表示dis<=dis[i]+j的i到n的方案数
    转移时把所有符合条件的都转移过来,如果发现某个dp同时出现说明有0环直接输出-1
    用记搜很好实现

    Code

    最终还是最短路写错了(T▽T)

    //By Menteur_Hxy
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define M(a,b) memset(a,(b),sizeof(a))
    #define F(i,a,b) for(register int i=(a);i<=(b);i++) 
    #define _E(i,u) for(register int i=_head[u];i;i=_nxt[i])
    #define E(i,u) for(register int i=head[u];i;i=nxt[i])
    using namespace std;
    typedef pair<int,int> PII;
    
    int read() {
    	int x=0,f=1; char c=getchar();
    	while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    
    const int N=100010,M=200010;
    int n,m,K,MOD,cnt,_cnt;
    int dis[N],nxt[M],_nxt[M],to[M],_to[M],w[M],_w[M],head[N],_head[N],vis[N],dp[N][60],in[N][60];
    vector <int> V[N];
    
    void dij() {
    	priority_queue<PII,vector<PII>,greater<PII> > Q;
    	Q.push(PII(dis[n]=0,n));
    	while(!Q.empty()) {
    		int u=Q.top().second,v; Q.pop();
    		if(vis[u]) continue; vis[u]=1;
    		E(i,u) if(dis[v=to[i]]>dis[u]+w[i]) {
    			dis[v]=dis[u]+w[i];
    			Q.push(PII(dis[v],v));
    		}
    	}
    }
    
    int dfs(int u,int k) {
    	if(in[u][k]) return -1;
    	if(dp[u][k]) return dp[u][k];
    	in[u][k]=1; dp[u][k]=(u==n);
    	int tmp,v,reg;
    	_E(i,u) if((tmp=dis[v=_to[i]]+_w[i]-dis[u])<=k) {
    		if((reg=dfs(v,k-tmp))==-1) return dp[u][k]=-1;
    		dp[u][k]=(dp[u][k]+reg)%MOD;
    	}
    	return in[u][k]=0,dp[u][k];
    }
    
    #define _add(a,b,c) _nxt[++_cnt]=_head[a],_to[_cnt]=b,_w[cnt]=c,_head[a]=_cnt
    #define add(a,b,c) nxt[++cnt]=head[a],to[cnt]=b,w[cnt]=c,head[a]=cnt
    int main() {
    	int T=read();
    	while(T--) {
    		_cnt=cnt=0;M(dis,0x3f);M(head,0);M(vis,0);M(dp,0),M(in,0),M(_head,0);
    		n=read(),m=read(),K=read(),MOD=read();
    		F(i,1,n) V[i].clear();
    		F(i,1,m) {
    			int a=read(),b=read(),c=read();
    			add(b,a,c); _add(a,b,c);
    		}
    		dij();
    		printf("%d
    ",dfs(1,K));
    	}
    	return 0;
    }
    
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    animate动画回调函数
    triggerHandler不执行事件默认值
    trigger自动执行事件
    js与jquery对象的互转
    让低版本浏览器支持html5的标签
    闭包的好处罗列
    AJAX跨域
    php能干什么?
    concat() 方法用于连接两个或多个数组。
    使用 v-cloak 防止页面加载时出现 vuejs 的变量名
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9361854.html
Copyright © 2011-2022 走看看