LOJ P3953 逛公园 NOIP dp 最短路 拓扑排序
https://www.luogu.org/problemnew/show/P3953
开o2过了不开o2re一个点。。。写法如题
顺便一提这道题在我校oj是a不了的因为我校土豆服务器速度奇慢1s时限
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=;
int n,m,k,p;
struct nod{
int y,v,next;
}e[][maxn*];
int head[][maxn]={};
int dis[][maxn]={};
int d[maxn]={},zz[maxn]={};
int mx,cnt=,ans=,tot=;
int f[][maxn]={};
bool vis[maxn]={};
queue< int >q;
void init(int x,int y,int v){
e[][++tot].y=y;e[][tot].v=v;e[][tot].next=head[][x];head[][x]=tot;
e[][tot].y=x;e[][tot].v=v;e[][tot].next=head[][y];head[][y]=tot;
}
void SPFA(int x,int z){
for(int i=;i<=n;i++)vis[i]=;
q.push(x);vis[x]=;dis[z][x]=;
int y,v,v1;
while(!q.empty()){
x=q.front();q.pop();v=dis[z][x];
for(int i=head[z][x];i;i=e[z][i].next){
y=e[z][i].y;v1=e[z][i].v;
if(dis[z][y]>v+v1){
dis[z][y]=v+v1;
if(!vis[y])q.push(y);
vis[y]=;
}
}
vis[x]=;
}
}
bool Topsort(){
for(int i=;i<=n;i++)d[i]=;
for(int i=;i<=n;i++){
for(int j=head[][i];j;j=e[][j].next){
if(e[][j].v+dis[][i]==dis[][e[][j].y])d[e[][j].y]++;//按照最短路连边
}
}cnt=;
for(int i=;i<=n;i++)if(!d[i])zz[++cnt]=i;
for(int i=;i<=cnt;i++){
for(int j=head[][zz[i]];j;j=e[][j].next){
if(e[][j].v+dis[][zz[i]]==dis[][e[][j].y]){
d[e[][j].y]--;
if(!d[e[][j].y])zz[++cnt]=e[][j].y;
}
}
}
for(int j=;j<=n;j++){//如果有0边构成的环,那么这个环一定到最后也有d
if(d[j]&&dis[][j]+dis[][j]<=k+dis[][n])return ;//如果环在合法路上就不用dp了有无数种方案
}return ;
}
void DP(){
for(int i=;i<=k;i++)
for(int j=;j<=n;j++)f[i][j]=;
ans=;f[][]=;
int y,v,x;
for(int i=;i<=k;i++){
for(int j=;j<=cnt;j++){
x=zz[j];if(dis[][x]==mx)continue;
for(int w=head[][x];w;w=e[][w].next){
y=e[][w].y;v=e[][w].v;
if(dis[][x]+v==dis[][y])f[i][y]=(f[i][y]+f[i][x])%p;//用拓扑序给f[k][i]汇总一下
}
}
for(int j=;j<=n;j++){//f[k][x]往下延伸
x=j;if(dis[][x]==mx)continue;
for(int w=head[][x];w;w=e[][w].next){
y=e[][w].y;v=e[][w].v;
if(dis[][x]+v!=dis[][y]){
if(i+dis[][x]+v-dis[][y]<=k)
f[i+dis[][x]+v-dis[][y]][y]=(f[i+dis[][x]+v-dis[][y]][y]+f[i][x])%p;
}
}
}ans=(ans+f[i][n])%p;
}
}
int main(){
//freopen("now.in","r",stdin);
int T;scanf("%d",&T);mx=(int)1e8;
while(T-->){
scanf("%d%d%d%d",&n,&m,&k,&p);
for(int i=;i<=n;i++)dis[][i]=dis[][i]=mx;
for(int i=;i<=n;i++)head[][i]=head[][i]=;tot=;
int x,y,v;
for(int i=;i<=m;i++){
scanf("%d%d%d",&x,&y,&v);init(x,y,v);
}
SPFA(,);SPFA(n,);//cout<<dis[1][1]<<dis[0][n]<<endl;
if(dis[][]==mx)printf("0\n");
else{
if(Topsort()){
printf("-1\n");
}
else{
DP();
printf("%d\n",ans);
}
}
}
return ;
}
LOJ P3953 逛公园 NOIP dp 最短路 拓扑排序的更多相关文章
- NOIP2017逛公园(dp+最短路)
策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会 ...
- 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索
题目描述 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策 ...
- [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 ...
- [Luogu P3953] 逛公园 (最短路+拓扑排序+DP)
题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易 ...
- P3953 逛公园(dp,最短路)
P3953 逛公园 题目描述 策策同学特别喜欢逛公园.公园可以看成一张NN个点MM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,NN号点是公园的出口,每条边有一个非负权值, 代表策策经 ...
- 【洛谷】3953:逛公园【反向最短路】【记忆化搜索(DP)统计方案】
P3953 逛公园 题目描述 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条 ...
- Luogu P3953 逛公园(最短路+记忆化搜索)
P3953 逛公园 题面 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园的入口,\(N\) 号点是公 ...
- [NOIP2017]逛公园 最短路+拓扑排序+dp
题目描述 给出一张 $n$ 个点 $m$ 条边的有向图,边权为非负整数.求满足路径长度小于等于 $1$ 到 $n$ 最短路 $+k$ 的 $1$ 到 $n$ 的路径条数模 $p$ ,如果有无数条则输出 ...
- [LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset)
[LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset) 题面 题面较长,略 分析 首先,发现火星人只有死和活两种状态,考虑2-SAT 建图 ...
随机推荐
- 引发类型为“System.OutOfMemoryException”的异常
在运维工作中,经常能接到客户的反馈这个:引发类型为“System.OutOfMemoryException”的异常.客户反馈物理内存都还有富余,怎么报内存不足的错误呢! 什么时候会引发System.O ...
- [转]C++ 取代switch的三种方法
1.常规switch enum EnumType { enumOne, enumTwo, enumThree }; void showMessage(int type) { switch(type) ...
- 20165320 预备作业2:技能学习心得与C语言学习
一.技能学习心得 1.你有什么技能比大多数人好? 我觉得我的篮球打得比一般的人好吧,但是也仅仅掌握了大部分基本的篮球技巧,算不上精通. 2.针对这个技能的获取你有什么成功的经验? 我觉得要打好篮球需要 ...
- Python——脚本(calculator)
<Python基础教程>(第二版) P123 书中原代码如下: class Calculator: def calculator(self,expression): self.value ...
- 2016.5.16——leetcode:Reverse Bits(超详细讲解)
leetcode:Reverse Bits 本题目收获 移位(<< >>), 或(|),与(&)计算的妙用 题目: Reverse bits of a given 3 ...
- zTree静态树与动态树的用法——(七)
0.[简介] zTree 是利用 JQuery 的核心代码,实现一套能完成大部分常用功能的 Tree 插件 兼容 IE.FireFox.Chrome 等浏览器 在一个页面内可同时生成多个 Tree 实 ...
- 终端多窗口分屏Terminator
1.安装 Terminator最大的特点就是可以在一个窗口中打开多个终端 sudo apt-get install terminator 2.快捷键 Ctrl+Shift+E 垂直分割窗口 Ctrl+ ...
- SQLAlchemy-对象关系教程ORM-create
ORM是建立在SQL语言构造器之上的工具集,用于将Python对象映射到数据库的行,提供了一系列接口用于从数据库中存取对象(行).在ORM 工作时,在底层调用SQL语言构造器的API,这些通用的操作有 ...
- Linux下配置Samba服务器全过程
Linux下配置Samba服务器全过程 user级别的samba的配置 http://www.linuxidc.com/Linux/2014-11/109234.htm http://www.linu ...
- python版本共存
要玩多版本最好使用虚拟环境,避免根python切换及包误安装的麻烦 1.直接安装实现 1.1 windows下 到官网(https://www.python.org/downloads/)下载,如py ...