【NOIP2017】逛公园 最短路+DP
诶,去年场上不会处理$0$的环,只拿了$60$有点可惜。
我们先不管边边权为$0$的边。
我们先跑一次最短路,令$dis[u]$表示从$1$至$u$的最短路的长度。
那么根据题目的要求,从起点走到$u$号点的路径长度只可能在区间$[dis[u],dis[u]+k]$中。
令$f[i][j]$表示当前从起点走到$i$,行走的路程为$dis[i]+j$的方案数。
不妨发现这个东西可以通过类似分层图最短路的方式进行更新,然后就直接更新就行了。
然而这一题中有部分点存在边权为$0$的边,一旦走入一个$0$环的话采用上述的方法会$TLE$。
于是我们把上面的通过分层图最短路的更新方式,更换为记忆化搜索,我们在当前搜索的路径上打上标记,然后若走到之前标记过的点,那么直接输出$-1$退出即可。这种方式可以有效避免将无需经过的零环纳入考虑范围内。
(可能是个人写法的原因),经过$1$的零环需要特判,直接在最短路里判掉就好了。
然后就没了。时间复杂度:$O(mk+m log n)$。
#include<bits/stdc++.h>
#define M 100005
using namespace std; struct edge{int u,v,next;}e[M*]={}; int head[M]={},head1[M]={},use=;
void add(int x,int y,int z){use++;e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use;}
void add1(int x,int y,int z){use++;e[use].u=y;e[use].v=z;e[use].next=head1[x];head1[x]=use;}
int n,m,k,MOD; struct node{
int x,dis;
node(){x=dis=;}
node(int xx,int ddis){x=xx; dis=ddis;}
friend bool operator <(node a,node b){return a.dis>b.dis;}
}a[M];
priority_queue<node> q;
int vis[M]={},dis[M]={},v[M][]={},f[M][]={},in[M][]={};
int dij(){
q.push(node(,));
while(!q.empty()){
node U=q.top(); q.pop();
int u=U.x;
if(vis[u]) continue;
vis[u]=; dis[u]=U.dis;
for(int i=head[u];i;i=e[i].next){
if(dis[u]+e[i].v==&&e[i].u==) return ;
if(!vis[e[i].u]) q.push(node(e[i].u,dis[u]+e[i].v));
}
}
return ;
} int dfs(int x,int p){
if(f[x][p]!=-) return f[x][p];
if(in[x][p]) return -;
int res=; in[x][p]=;
for(int i=head1[x];i;i=e[i].next){
int v=dis[x]-dis[e[i].u]+p-e[i].v;
if(<=v&&v<=k){
int now=dfs(e[i].u,v);
if(now==-) return -;
res=(res+now)%MOD;
}
}
f[x][p]=res; in[x][p]=;
return res;
} int Main(){
memset(vis,,sizeof(vis)); memset(dis,,sizeof(dis));
memset(f,-,sizeof(f)); memset(e,,sizeof(e));
memset(head,,sizeof(head)); memset(head1,,sizeof(head1)); use=;
memset(in,,sizeof(in));
memset(v,,sizeof(v));
scanf("%d%d%d%d",&n,&m,&k,&MOD);
for(int i=;i<=m;i++){
int x,y,z; scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add1(y,x,z);
}
if(dij()==){printf("-1\n"); return ;}
int ans=; f[][]=;
for(int i=;i<=k;i++){
int now=dfs(n,i);
if(now==-){
printf("-1\n");
return ;
}
ans=(ans+now)%MOD;
}
printf("%d\n",ans);
} int main(){
int cas; cin>>cas;
while(cas--) Main();
}
【NOIP2017】逛公园 最短路+DP的更多相关文章
- [NOIP2017]逛公园 最短路+拓扑排序+dp
题目描述 给出一张 $n$ 个点 $m$ 条边的有向图,边权为非负整数.求满足路径长度小于等于 $1$ 到 $n$ 最短路 $+k$ 的 $1$ 到 $n$ 的路径条数模 $p$ ,如果有无数条则输出 ...
- [NOIP2017]逛公园 最短路图 拓扑序DP
---题面--- 题解: 挺好的一道题. 首先我们将所有边反向,跑出n到每个点的最短路,然后f[i][j]表示从i号节点出发,路径长比最短路大j的方案数. 观察到,如果图中出现了0环,那么我们可以通过 ...
- [NOIP2017] 逛公园 解题报告(DP)
我很不想说 在我的AC代码上我打了表,但实在没有办法了.莫名的8,9个点RE.然而即便是打表...也花了我很久. 这大概是NOIP2017最难的题了,为了让不懂的人更容易理解,这篇题解会比较详细 我的 ...
- [NOIP2017] 逛公园 (最短路,动态规划&记忆化搜索)
题目链接 Solution 我只会60分暴力... 正解是 DP. 状态定义: \(f[i][j]\) 代表 \(1\) 到 \(i\) 比最短路长 \(j\) 的方案数. 那么很显然最后答案也就是 ...
- 洛谷 P3953 [ NOIP 2017 ] 逛公园 —— 最短路DP
题目:https://www.luogu.org/problemnew/show/P3953 主要是看题解...还是觉得好难想啊... dfs DP,剩余容量的损耗是边权减去两点最短路差值...表示对 ...
- 【题解】NOIP2017逛公园(DP)
[题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...
- [NOIP2017] 逛公园
[NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^ ...
- 【比赛】NOIP2017 逛公园
考试的时候灵光一闪,瞬间推出DP方程,但是不知道怎么判-1,然后?然后就炸了. 后来发现,我只要把拓扑和DP分开,中间加一个判断,就AC了,可惜. 看这道题,我们首先来想有哪些情况是-1:只要有零环在 ...
- NOIP2017逛公园(dp+最短路)
策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会 ...
随机推荐
- Maximum profit of stocks
https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Moc ...
- 2018.08.30 bzoj4318: OSU!(期望dp)
传送门 简单期望dp. 感觉跟Easy差不多,就是把平方差量进阶成了立方差量,原本维护的是(x+1)2−x2" role="presentation" style=&qu ...
- 2018.08.29 hdu3507 Print Article(斜率优化dp)
传送门 这应该算是斜率优化的模板题了. 就是要求打印n个数,每个数有一个参数a[i],每打印一段连续的数[l,r]需要的花费是(a[[l]+...+a[r])2+m" role=" ...
- 2018.08.21 bzoj4668: 冷战(并查集+启发式合并)
传送门 可以发现需要维护连通性和两点连通时间. 前者显然是并查集的常规操作,关键就在于如何维护两点的连通时间. 然后会想到这个时候不能用路径压缩了,因为它会破坏原本树形集合的结构,因此可以启发式按si ...
- hdu-1394(线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 思路:建立一个空线段树,求出逆序数,(逆序数性质:交换两个相邻数,逆序数+1或-1, 交换两个不 ...
- jdk10运行springboot项目出现:Type javax.xml.bind.JAXBContext not present
项目由openjdk8.0迁移到jdk10导致的 原因:java9模块化的概念使得JAXB默认没有加载: jaxb-api是存在jdk中的,只是默认没有加载而已,手动引入即可. 推荐方式: <! ...
- Java源码更改的方式
1.找到要改的类所在包名地址. 比如标签名的更改: <s:debug></s:debug> (1)ctril+鼠标左键========双击标签,就会弹出标签所在的类的文本 (2 ...
- 20155305乔磊2016-2017-2《Java程序设计》第七周学习总结
教材学习内容总结 第十二章 Lambda 12.1 认识Lambda语法 - Lambda 教材的引入循序渐近.深入浅出 如果使用JDK8的话,可以使用Lambda特性去除重复的信息,例: Compa ...
- jdk tomcat maven svn plsql客户端 环境变量配置整理
1 jdk 新建: 1.JAVA_HOME ----- C:\Program Files\Java\jdk1.7.0 2.CLASSPATH ------ .;%JAVA_HOME%\li ...
- delphi自带的SHA1算法
delphi自带的SHA1算法 uses IdHashSHA, IdGlobal; function SHA1(Input: String): String; begin with TIdHashSH ...