洛谷P3953 [NOIP2017]逛公园
K<=50,感觉可以DP
先建反图求出从n到各个点的最短路,然后在正图上DP
设f[当前点][比最短路多走的距离]=方案数
转移显然是 $f[v][res]=\sum f[u][res+tmp]$ tmp是从v到u比最短路多走的路程
注意如果图中有0环,则有无穷多种方案。
判0环可以DFS判,也可以把最短路边和0权边建在一个新图上,用拓扑排序判(显然前者更简单)
/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct edge{
int v,nxt,w;
}e[mxn<<],er[mxn<<];
int hd[mxn],mct=;
int hdr[mxn],rct=;
void add_edge(int u,int v,int w){
e[++mct].v=v;e[mct].nxt=hd[u];e[mct].w=w;hd[u]=mct;return;
}
void add_edgeR(int u,int v,int w){
er[++rct].v=v;er[rct].nxt=hdr[u];er[rct].w=w;hdr[u]=rct;return;
}
int dis[mxn];
bool inq[mxn];
int vis[mxn];
queue<int>q;
int n,m,K,P;
void SPFA(int s){//反图SPFA
memset(dis,0x3f,sizeof(dis));
dis[s]=;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();inq[u]=;
for(int i=hdr[u];i;i=er[i].nxt){
int v=er[i].v;
if(dis[v]>dis[u]+er[i].w){
dis[v]=dis[u]+er[i].w;
if(!inq[v]){ inq[v]=; q.push(v); }
}
}
}
return;
}
inline void add(int &a,int b){
a+=b; a=(a>P)?(a-P):a; return;
}
int f[mxn][];
int ind[mxn];//时间戳
int cir;
int DP(int u,int res){
// printf("in:%d %d\n",u,res);
if(vis[u] && ind[u]==res){cir=;return ;}
if(f[u][res]!=-)return f[u][res];
int tmp=;
if(u==n && !res)tmp++;//return 1影响判环
vis[u]++;
ind[u]=res;
//
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
int x=res-(e[i].w-(dis[u]-dis[v]));
if(x>= && x<=K)
add(tmp,DP(v,x));
if(cir)return ;
}
//
vis[u]--;
ind[u]=;
return f[u][res]=tmp;
}
void init(){
memset(f,-,sizeof f);
memset(hd,,sizeof hd);
memset(hdr,,sizeof hdr);
memset(ind,,sizeof ind);
memset(vis,,sizeof vis);
mct=;rct=;cir=;
return;
}
int main(){
int i,j,u,v,w,ans;
int T=read();
while(T--){
init();
n=read();m=read();K=read();P=read();
for(i=;i<=m;i++){
u=read();v=read();w=read();
add_edge(u,v,w);
add_edgeR(v,u,w);
}
SPFA(n);
ans=;
for(i=;i<=K;i++){
add(ans,DP(,i));
if(cir)break;
}
if(cir) puts("-1");
else printf("%d\n",ans);
}
return ;
}
洛谷P3953 [NOIP2017]逛公园的更多相关文章
- 【题解】洛谷P3953 [NOIP2017TG] 逛公园(记忆化搜索+SPFA)
题目来源:洛谷P3953 思路 先用SPFA求一遍最短路 在求最短路的同时可以把所有点到终点的最短路求出来 dis数组 注意要反向SPFA 因为从起点开始可能会走到一些奇怪的路上导致时间负责度增加 ...
- 洛谷3953 (NOIp2017) 逛公园——记忆化搜索+用栈判0环
题目:https://www.luogu.org/problemnew/show/P3953 因为K只有50,所以想到用dp[ cr ][ j ]表示在点cr.比最短路多走了 j 的方案数.(看了TJ ...
- 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)
P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...
- 洛谷P4513 小白逛公园
区间最大子段和模板题.. 维护四个数组:prefix, suffix, sum, tree 假设当前访问节点为cur prefix[cur]=max(prefix[lson],sum[lson]+pr ...
- 2018.07.23 洛谷P4513 小白逛公园(线段树)
传送门 线段树常规操作了解一下. 单点修改维护区间最大连续和. 对于一个区间,维护区间从左端点开始的连续最大和,从右端点开始的连续最大和,整个区间最大和,区间和. 代码如下: #include< ...
- Luogu P3953 [NOIP2017]逛公园
题目 首先我们跑出从\(1\)出发的最短路\(d1\)和反图上从\(n\)出发的最短路\(dn\). 然后我们处理出长度不超过\(d1_n+k\)的最短路边集,给它拓扑排序. 如果存在环,那么这个环一 ...
- 洛谷P4513 小白逛公园 (线段树)
这道题看起来像是线段树和最大子段和的结合,但这里求最大子段和不用dp,充分利用线段树递归的优势来处理.个人理解:线段树相当于把求整个区间的最大子段和的问题不断划分为很多个小问题,容易解决小问题,然后递 ...
- NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
原文链接https://www.cnblogs.com/zhouzhendong/p/9258043.html 题目传送门 - 洛谷P3953 题目传送门 - Vijos P2030 题意 给定一个有 ...
- [NOIP2017] 逛公园
[NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^ ...
随机推荐
- 四人小组:vip会员管理系统
需求概述: 针对各类商铺百花齐放的现状,越来越多的商家考虑用各种方式招揽顾客,会员制度一向是吸引回头客的不二法宝.用户持有会员卡能够迅捷的购物,享有普通顾客更多的优惠或回馈.乃至新品推送.积分等一系列 ...
- JMeter性能测试基础 (3) - 使用参数文件做搜索引擎性能对比
本篇文章主要对如何在JMeter中进行URL的参数进行配置进行介绍,通过CSV文件配置参数数据,对baidu.sogou.haosou进行搜索性能对比测试. 1.建立测试计划.线程组,并在线程组下添加 ...
- git 常用命令总结(一)
1.初始化版本库: .进入工程根目录目录 .创建项目目录 mkdir 项目目录名称 .进入创建的项目中 cd 项目名称 pwd 显示当前目录 .项目初始化 git init //完成后会在项目目录下生 ...
- [转帖]go 命令
golang笔记——命令 https://www.cnblogs.com/tianyajuanke/p/5196436.html 1.GO命令一览 GO提供了很多命令,包括打包.格式化代码.文档生成 ...
- Office/Visio/Project 2010 RTM (x86) (x64)(中文简体/英文)
1.cn_office_professional_plus_2010_x64_515528.exe ed2k://|file|cn_office_professional_plus_2010_x64_ ...
- P2144 [FJOI2007]轮状病毒
题目描述 轮状病毒有很多变种.许多轮状病毒都是由一个轮状基产生.一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成.2个原子之间的边表示这2个原子之间的信息通道,如图1. n轮状病毒的产生规律 ...
- JVM调优及参数设置
(1)参数 -Xms:初始堆大小 -Xmx :最大堆大小 此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存 -Xmn :年轻代大小 整个堆大小=年轻代大小 + 年老代大小 + 持 ...
- 记一次java程序out of memory问题
在一个比较大批量的pdf转String项目中遇到了:java.lang.OutOfMemoryError: Java heap space错误 第一反应肯定是程序没有写好,大量循环时没有把程序中没有用 ...
- 【刷题】HDU 1853 Cyclic Tour
Problem Description There are N cities in our country, and M one-way roads connecting them. Now Litt ...
- yii2 查询数据库语法
$query0 = ImGroupUser::find()->where(['gid'=>'56680dfc60b215d62104a4d8'])->select('user_cli ...