逛公园

传送门

解法:

先不考虑0环
很容易想到dp
状态转移方程也很容易想到

\(d[i]\)为n到i的最短路长度 当然此时是反向图
反向图是为了防止1能到达的点到达不了n而出错
\(dp[i][j]\)表示到达i点距离为\(d[i]+j\)的路径个数

x->y有路径 \(dp[x][k]=dp[y][k-(d[y]+edge(x,y)-d[x])]\ (0\le d[y]+edge(x,y)-d[x]\le k)\) 此时为正向图

当然dp在这种图中不好实现
改成记忆化搜索


有些点反向图n到达的了而正向图1到达不了
这些点在正向图搜索时不可能收到
而当
有些点反向图n到达不了而正向图1到达的了
这些点的d[]值为“正无穷”
此时\(d[y]+edge(x,y)-d[x]\)要么小于0要么大于k
所以对答案也无影响

再考虑0环
若一次深搜时出现两次(i,j)
那么一定有0环 想一想就知道了

这时输出-1结束就行

否则 最终答案就是 \(\sum_{i=0}^kdp[1][i]\)

代码:

第一种:最好理解 前缀和在主程序中处理 但是评测姬一累就会凉凉

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#define inf 2000000000
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(register int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
int T,n,m,k,mod,ans;
int d[100010],dp[100010][55];
int tot,head[100010],tt,rev[100010];
bool cmp,vis[100010],v[100010][55];
queue<int> que;
struct EDGE
{int to,nxt,d;
}edge[200010],reve[200010];
inline void add(int u,int v,int d)
{edge[++tot].to=v;edge[tot].d=d;edge[tot].nxt=head[u];head[u]=tot;
}
inline void addr(int u,int v,int d)
{reve[++tt].to=v;reve[tt].d=d;reve[tt].nxt=rev[u];rev[u]=tt;
}
inline int read()
{int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}return x;
}
inline void spfa()
{d[n]=0;que.push(n);while(!que.empty()){int x=que.front();que.pop();vis[x]=0;for(int i=rev[x];i;i=reve[i].nxt){int y=reve[i].to,dis=reve[i].d;if(d[y]>d[x]+dis){d[y]=d[x]+dis;if(!vis[y]) vis[y]=1,que.push(y);}}}
}
int getdp(int x,int t)
{if(v[x][t]){v[x][t]=0;cmp=1;return 0;}if(dp[x][t]) return dp[x][t];v[x][t]=1;for(int i=head[x];i;i=edge[i].nxt){int y=edge[i].to;int dis=t-(d[y]+edge[i].d-d[x]);if(dis<0||dis>k) continue;dp[x][t]=(dp[x][t]+getdp(y,dis))%mod;if(cmp){v[x][t]=0;return 0;}}v[x][t]=0;if(x==n&&t==0) dp[x][t]=1;//为了排除过终点的零环 终点初始值需要放在此处处理return dp[x][t];
}
int main()
{T=read();while(T--){n=read(),m=read(),k=read(),mod=read();tot=1,tt=1;memset(head,0,sizeof(head));memset(rev,0,sizeof(rev));memset(d,0x3f,sizeof(d));memset(dp,0,sizeof(dp));rep(i,1,m){int u=read(),v=read(),d=read();add(u,v,d);addr(v,u,d);}spfa();ans=0,cmp=0;dwn(i,k,0)ans=(ans+getdp(1,i))%mod;if(cmp) printf("-1\n");else printf("%d\n",ans);}return 0;
}

第二种:getdp()在一边跑一边处理前缀和 很快

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#define inf 2000000000
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(register int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
int T,n,m,k,mod,ans;
int d[100010],dp[100010][55];
int tot,head[100010],tt,rev[100010];
bool cmp,vis[100010],v[100010][55];
queue<int> que;
struct EDGE
{int to,nxt,d;
}edge[200010],reve[200010];
inline void add(int u,int v,int d)
{edge[++tot].to=v;edge[tot].d=d;edge[tot].nxt=head[u];head[u]=tot;
}
inline void addr(int u,int v,int d)
{reve[++tt].to=v;reve[tt].d=d;reve[tt].nxt=rev[u];rev[u]=tt;
}
inline int read()
{int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}return x;
}
inline void spfa()
{d[n]=0;que.push(n);while(!que.empty()){int x=que.front();que.pop();vis[x]=0;for(int i=rev[x];i;i=reve[i].nxt){int y=reve[i].to,dis=reve[i].d;if(d[y]>d[x]+dis){d[y]=d[x]+dis;if(!vis[y]) vis[y]=1,que.push(y);}}}
}
int getdp(int x,int t)
{if(v[x][t]){v[x][t]=0;cmp=1;return 0;}if(dp[x][t]) return dp[x][t];v[x][t]=1;for(int i=head[x];i;i=edge[i].nxt){int y=edge[i].to;int dis=t-(d[y]+edge[i].d-d[x]);if(dis<0||dis>k) continue;dp[x][t]=(dp[x][t]+getdp(y,dis))%mod;if(cmp){v[x][t]=0;return 0;}}v[x][t]=0;if(x==n) dp[x][t]+=1;//对比第一种 其实就是此处改了 因为dp[1][k]->dp[n][i]与dp[1][k-i]->dp[n][0]所得值为相同的 所以给dp[n][]全部赋值为1 用一次getdp(1,k)即可过return dp[x][t];
}
int main()
{T=read();while(T--){n=read(),m=read(),k=read(),mod=read();tot=1,tt=1;memset(head,0,sizeof(head));memset(rev,0,sizeof(rev));memset(d,0x3f,sizeof(d));memset(dp,0,sizeof(dp));rep(i,1,m){int u=read(),v=read(),d=read();add(u,v,d);addr(v,u,d);}spfa();cmp=0;ans=getdp(1,k);if(cmp) printf("-1\n");else printf("%d\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/MYsBlogs/p/11068548.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462265.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

poj2299 ( bit )

树状数组求逆序数&#xff0c;先排个序&#xff0c;从大到小往插&#xff0c;计算在他的前面有几个比他大&#xff0c;就是他的逆序数。 &#xff08;PS&#xff1a;最近对数量越来越不敏感了&#xff0c;老在这上面错。多做题&#xff0c;不能断啊&#xff09; 1 #include <…

Linux下编译安装openssl

(1) 下载openssl压缩包。在 http://www.openssl.org/source/ 选择合适版本的压缩包&#xff0c;一般选择标记有“[LATEST]”的包&#xff0c;假设其link为 http://www.openssl.org/source/openssl-1.0.1c.tar.gz&#xff0c;用下面的下载&#xff1a; # wget http://www.openss…

前端小插件之手写js循环滚动特效

很多前端都离不开滚动的特效&#xff0c;调用插件繁琐&#xff0c;后期更改麻烦&#xff0c;考虑到这些因素&#xff0c;自己写了一套无限循环滚动的小特效。 首先滚动特效很好写&#xff0c;用css就可以完成&#xff0c;下面写一个基础css向上循环滚动特效 html <div class…

敏捷开发一千零一问系列之七:怎样对待有看法的徒弟?

这是敏捷开发一千零一问系列的第七篇。&#xff08;之一&#xff0c;之二&#xff0c;之三&#xff0c;问题总目录&#xff09;问题松结对编程中&#xff0c;师傅对徒弟安排任务时&#xff0c;对于有想法的徒弟提出的意见怎样解决&#xff1f;方案步骤0&#xff1a;正心&#x…

SSH远程登录失败,提示“Password authentication failed”

使用SecureCRT登陆&#xff0c;提示“Password authentication failed” 使用linux下ssh登陆&#xff0c;提示“Permission denied, please try again.” 网上收集的相关资料&#xff1a; 方法一&#xff1a; 1. vi服务器端的/etc/ssh/sshd_config 2. 把PasswordAuthentication…

触摸传感器

void setup() {pinMode(A5,INPUT); //设置引脚 A5 为输出模式 Serial.begin(9600); //设置波特率为9600 } void loop() { // put your main code here, to run repeatedly: Serial.println(analogRead(A5)); //串口输出 A5读取到的值 delay(200); //延时200毫秒 } 转…

ORACLE查询表最近更改的数据

&#xff0c;今天开发人员问我如何快速并方便的查出一张表最近被更改的记录&#xff0c;这个需求很简单&#xff0c;由于是查最近被更改的数据&#xff0c;查回滚段就可以&#xff0c;下面是我做的小实验。 SQL> create table test(id number,name varchar2(10),gender varc…

学滑冰

为什么80%的码农都做不了架构师&#xff1f;>>> http://www.cnr.cn/wcm/zhuanti/harb/bxyd/t20041230_163420.html 学滑冰&#xff08;一&#xff09; 到冰场上穿冰刀奔驰豪情一番&#xff0c;真是今人激情万千&#xff0c;你会滑冰吗&#xff1f;如果你还不会滑冰…

锡安赞歌 mp3下载

《锡安赞歌》mp3下载地址:http://pan.baidu.com/s/1i3nJLml

Java-Redis 热部署问题

项目请求时报错&#xff1a;java.lang.ClassCastException: cn.xingaohbd.seckil.model.User cannot be cast to cn.xingaohbd.seckil.model.User at cn.xingaohbd.seckil.service.impl.UserServiceImpl.getUser(UserServiceImpl.java:33) ~[classes/:na] at cn.xingaohbd.seck…

dp之二维背包poj1837(天平问题 推荐)

题意&#xff1a;给你c&#xff08;2<c<20&#xff09;个挂钩&#xff0c;g&#xff08;2<g<20&#xff09;个砝码&#xff0c;求在将所有砝码&#xff08;砝码重1~~25&#xff09;挂到天平(天平长 -15~~15)上&#xff0c;并使得天平平衡的方法数....... 思路&…

Gridview SummaryItem 格式化数字

DisplayFomrat{0:#.##}转载于:https://www.cnblogs.com/gaoshoubuduo/archive/2012/02/01/2334533.html

js注释

介绍 作用 合作分享&#xff1a;方便他人阅读&#xff0c;便于分享 沉淀总结&#xff1a;容易忘记代码&#xff0c;自己总结沉淀 形式 1.// 双斜杠 2&#xff0e;/**/斜杠星号 常用标签 标签 描述 module 标明当前文件模块&#xff0c;在这个文件中的所有成员将被默认为属于…

谁获得了最高奖学金

谁获得了最高奖学金http://acm.nyist.net/JudgeOnline/problem.php?pid60 时间限制&#xff1a;1000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;2描述某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种&#xff0c;获取的条件各自不同&#xff…

vs2013编译boost1.55.0 32/64位

在使用vs2013编译boost-1.55.0之前&#xff0c;先要给boost做下修改&#xff1a; boost_1_55_0\boost\intrusive\detail\has_member_function_callable_with.hpp line:222 template<class U> static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION…

简评知乎的优点与不足

首先说知乎好在什么地方&#xff1f; 1、我认为知道好在知乎的真实性。 因为真实&#xff0c;大家在问问题和回答问题的时候就比较负责。这一点很关键。如果没有了这一点&#xff0c;那就成了类似百度知道的东西&#xff0c;也就没必要存在了。 2、页面简洁友好。 没有广告&…

ICE简单介绍及使用示例

1、ICE是什么&#xff1f; ICE是ZEROC的开源通信协议产品&#xff0c;它的全称是&#xff1a;The Internet Communications Engine&#xff0c;翻译为中文是互联网通信引擎&#xff0c;是一个面向对象的中间件&#xff0c;使我们能够以最小的代价构建分布式应用程序。ICE使我们…

AtCoder Grand Contest 017

AtCoder Grand Contest 017 A - Biscuits 有\(n\)个数&#xff0c;问有多少个集合的数的和模\(2\)余\(P\)。 随便\(dp\)一下就好了。 #include<iostream> #include<cstdio> using namespace std; #define ll long long inline int read() {int x0;bool tfalse;char…

PowerDesigner 把Comment写到name中 和把name写到Comment中 pd7以后版本可用

在使用PowerDesigner对数据库进行概念模型和物理模型设计时&#xff0c;一般在NAME或Comment中写中文&#xff0c;在Code中写英文。Name用来显 示&#xff0c;Code在代码中使用&#xff0c;但Comment中的文字会保存到数据库Table或Column的Comment中&#xff0c;当Name已经存在…

CentOS 6.2 安装教程

一、CentOS简介 CentOS是Linux的发行版之一&#xff0c;它安全、稳定、高效&#xff0c;是我最喜欢的Linux发行版之一。CentOS根据Red Hat Enterprise Linux开放源代码编译而成&#xff0c;与RedHat Linux并没有什么本质上的差别。但Red Hat Enterprise Linux是商业软件&#x…