洛谷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^ ...
随机推荐
- IT行业的个人见解
IT这个行业是近代历史上的新新行业,它的就业前景是非常的好的,就业率高,但是这个行业的需求人才精英不是那些半桶水的所谓IT男.我现在学习的是计算机专业中的软件工程目标是成为一名合格的软件工程师,软件工 ...
- windows多线程(三) 原子操作
一.分析上一篇程序的现象 我们先从上一篇文章中的最后一个程序开始分析. #include <stdio.h> #include <windows.h> const unsign ...
- Sysprep错误一则
准备搭建一台基于Windows2008的域控,通过ISO文件装完系统后,照例使用Windows Update打全了补丁.同时,考虑到经常使用Powershell,所以手动再装上了PS5.1 .因为准备 ...
- 用python和unittest编写app自动化测试用例
import unittest import webdriver import time class Test(unittest.TestCase): @classmethod def setUpCl ...
- HDU4791_Alice's Print Service
全场最水题. 保留打印a[i]份分别需要的钱,从后往前扫一遍,保证取得最优解. 查找的时候,二分同时判断最小值即可. 注意初值的设定应该设定为long long 的无穷大. #include < ...
- 绿色计算大赛决赛 第二阶段 消息传递(斯坦纳树 状压dp+spfa)
传送门 Description 作为公司老板的你手下有N个员工,其中有M个特殊员工.现在,你有一个消息需要传递给你的特殊员工.因为你的公司业务非常紧张,所以你和员工之间以及员工之间传递消息会造成损失. ...
- java 对象的解释过程
- Linux gcc和gdb程序调试用法 {转}
gcc一般调试格式: gcc -Wall -o test test.c // -wall 显示程序错误详细信息 gcc -v // 显示gcc的版本 gcc -o{1,2,3} t ...
- H5页面遮罩弹框下层还能滚动的问题
在页面上显示一个遮罩层,这是非常常见的操作,在遮罩层上操作,下层也会默认跟随手指滚动 此处就是要在显示遮罩的时候禁止下层滚动. 首先设置一个全局变量 var canScroll=false; 页面初始 ...
- Android之断点续传下载(转)
Android之断点续传下载http://www.cnblogs.com/zxl-jay/archive/2011/10/09/2204195.html