Luogu P3953 [NOIP2017]逛公园
题目
首先我们跑出从\(1\)出发的最短路\(d1\)和反图上从\(n\)出发的最短路\(dn\)。
然后我们处理出长度不超过\(d1_n+k\)的最短路边集,给它拓扑排序。
如果存在环,那么这个环一定是一个\(0\)环,此时是无解的。
否则我们把它的拓扑序跑出来。
对于一条边\((u,v,w)\),如果我们走这条边,会让路径长度比最短路大\(d1_u+w-d1_v\)。
那么我们设\(f_{i,j}\)表示走到第\(i\)个点,走过的路径长度是\(d1_i+j\)。
从小到大枚举\(j\),按拓扑序转移一遍,再把\(d1_u+w-d1_v\neq0\)的所有边转移一遍即可。
#include<bits/stdc++.h>
#define pi pair<int,int>
#define pb push_back
using namespace std;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
const int N=100007;
vector<pi>E[N];priority_queue<pi>q;stack<int>Q;
struct edge{int u,v,w;}e[N<<1];
int n,m,k,P,cnt,Tvis,dis[2][N],vis[N],deg[N],pos[N],f[N][51];
void inc(int &a,int b){a+=b,a=a>=P? a-P:a;}
void clearedge(){for(int i=1;i<=n;++i)E[i].clear();}
void cleardeg(){memset(deg,0,n+1<<2);}
void add(int u,int v,int w){E[u].pb(pi(v,w));}
void dij(int S,int id)
{
memset(dis[id],0x3f,n+1<<2),++Tvis,q.push(pi(dis[id][S]=0,S));int u;
while(!q.empty())
{
u=q.top().second,q.pop();if(vis[u]==Tvis)continue;vis[u]=Tvis;
for(auto [v,w]:E[u])if(dis[id][u]+w<dis[id][v])dis[id][v]=dis[id][u]+w,q.push(pi(-dis[id][v],v));
}
}
void toposort()
{
cnt=0;int u;Q.push(1);
while(!Q.empty())
{
u=Q.top(),Q.pop(),pos[++cnt]=u;
for(auto [v,w]:E[u])if(!(--deg[v]))Q.push(v);
}
}
int main()
{
int i,j,flg;
for(int T=read();T;--T)
{
n=read(),m=read(),k=read(),P=read();
for(i=1;i<=m;++i)e[i]=(edge){read(),read(),read()};
clearedge();
for(i=1;i<=m;++i)add(e[i].u,e[i].v,e[i].w);
dij(1,0);
clearedge();
for(i=1;i<=m;++i)add(e[i].v,e[i].u,e[i].w);
dij(n,1);
clearedge(),cleardeg();
for(i=1;i<=m;++i)if(dis[0][e[i].u]+dis[1][e[i].v]+e[i].w<=dis[0][n]+k&&dis[0][e[i].u]+e[i].w==dis[0][e[i].v])add(e[i].u,e[i].v,0),++deg[e[i].v];
for(i=1;i<=m;++i)e[i].w=dis[0][e[i].u]+e[i].w-dis[0][e[i].v];
toposort();
flg=0;
for(i=1;i<=n;++i)if(deg[i]){flg=1;break;}
if(flg){puts("-1");continue;}
memset(f,0,sizeof f),f[1][0]=1;
for(i=0;i<=k;++i)
{
for(j=1;j<=cnt;++j)for(auto [v,w]:E[pos[j]])inc(f[v][i],f[pos[j]][i]);
for(j=1;j<=m;++j)if(e[j].w&&i+e[j].w<=k)inc(f[e[j].v][i+e[j].w],f[e[j].u][i]);
}
for(i=flg=0;i<=k;++i)inc(flg,f[n][i]);
printf("%d\n",flg);
}
}
```
Luogu P3953 [NOIP2017]逛公园的更多相关文章
- Luogu 3953[NOIP2017] 逛公园 堆优化dijkstra + 记忆化搜索
题解 首先肯定是要求出单源最短路的,我用了堆优化dijikstra ,复杂度 mlogm,值得拥有!(只不过我在定义优先队列时把greater 打成了 less调了好久 然后我们就求出了$i$到源点的 ...
- 洛谷P3953 [NOIP2017]逛公园
K<=50,感觉可以DP 先建反图求出从n到各个点的最短路,然后在正图上DP 设f[当前点][比最短路多走的距离]=方案数 转移显然是 $f[v][res]=\sum f[u][res+tmp] ...
- [luogu P3953] [noip2017 d1t3] 逛公园
[luogu P3953] [noip2017 d1t3] 逛公园 题目描述 策策同学特别喜欢逛公园.公园可以看成一张$N$个点$M$条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,$N ...
- [NOIP2017] 逛公园
[NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^ ...
- 【比赛】NOIP2017 逛公园
考试的时候灵光一闪,瞬间推出DP方程,但是不知道怎么判-1,然后?然后就炸了. 后来发现,我只要把拓扑和DP分开,中间加一个判断,就AC了,可惜. 看这道题,我们首先来想有哪些情况是-1:只要有零环在 ...
- 【题解】NOIP2017逛公园(DP)
[题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...
- NOIP2017逛公园(dp+最短路)
策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会 ...
- NOIP2017 逛公园 题解报告 【最短路 + 拓扑序 + dp】
题目描述 策策同学特别喜欢逛公园.公园可以看成一张NNN个点MMM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,NNN号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花 ...
- [NOIP2017]逛公园 题解
我连D1T3都不会我联赛完蛋了 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 N 个点 M 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, N 号点是公园的出口,每条边有一个非负 ...
随机推荐
- 悲观锁,乐观锁以及MVCC
在上文中,我们探讨了MySQL不同存储引擎中的各类锁,在这篇文章中我们将要讨论的是MySQL是如何实现并发控制的.并发问题有三种,分别为: 读-读,不存在任何问题 读-写,有隔离性问题,可能遇到脏读( ...
- 51 Nod 1073 约瑟夫环
1073 约瑟夫环 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人 ...
- RedHat6.2系统安装ipvsadm+keepalived
一.安装IPVS 软件包下载: 链接:https://pan.baidu.com/s/1zNgPtALbdBTC1H6e0IaZPw 提取码:xm7t 1.检查内核模块,看一下ip_vs 是否被加载 ...
- 前端性能优化 —— reflow(回流/重排)和repaint(重绘)
简要:整个在浏览器的渲染过程中(页面初始化,用户行为改变界面样式,动画改变界面样式等)reflow(回流)和repaint(重绘) 会大大影响web性能,尤其是手机页面.因此我们在页面设计的时候要尽量 ...
- 缓存区溢出之slmail fuzzing
这是我们的实验环境 kali 172.18.5.118smtp windows2003 172.18.5.117 pop3 110 smtp 25 本机 172.18.5.114 已经知道slma ...
- jquery 动态增加删除行
最近写程序,碰巧有动态增加删除行,下面就记录一下 html就不写了,也没有什么,直接上核心了 新增行 function addRow(obj){ //获得table一共有多少行,方便追加的时候给序号赋 ...
- 讨厌的adb占用
adb重启的方法 2018年06月13日 14:59:47 丽闪无敌 阅读数:11969 执行以下命令: D:\android-sdks\platform-tools>adb kill-se ...
- C++入门经典-例4.11-名称空间的定义和使用
1:名称空间,也成为名字空间.命名空间,关键字为namespace.我们经常使用这样一条语句: using namespace std: 我们要使用标准输入输出流,除了包含它们所在的头文件外,还必须使 ...
- [翻译]C#中异步方法的性能特点
翻译自一篇博文,原文:The performance characteristics of async methods in C# 异步系列 剖析C#中的异步方法 扩展C#中的异步方法 C#中异步方法 ...
- android gradle,groovy--https://blog.csdn.net/hebbely/article/details/79074460
android grale,groovyhttps://blog.csdn.net/hebbely/article/details/79074460 Gradle编译时报错:gradle:peer n ...