题目大意:
  给你一个有向图,若用dis(u,v)表示从u到v的最短路长度,求从1到n的长度不超过dis(1,n)+k的路径数。

思路:
  首先分别预处理出以1,n为起点的单、源最短路。
  对于合法的边重构图,然后拓扑排序判环,
  BFS时判断一下当前点是否在合法路径上,
  如果最后一个点没有被搜到且在合法路径上,那么肯定是一个0环。
  最后动态规划,f[i][j]表示长度为dis(1,i)+j的路径数量。

 #include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<algorithm>
#include<functional>
#include<ext/pb_ds/priority_queue.hpp>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int inf=0x7fffffff;
const int N=,LIM=;
int n,m,lim,mod;
struct Edge {
int to,w;
};
std::vector<Edge> e0[N],e1[N];
inline void add_edge(const int &u,const int &v,const int &w) {
e0[u].push_back((Edge){v,w});
e1[v].push_back((Edge){u,w});
}
struct Vertex {
int id,dis;
bool operator > (const Vertex &another) const {
return dis>another.dis;
}
};
int dis0[N],dis1[N];
inline void dijkstra(const int &s,int dis[],const std::vector<Edge> e[]) {
static __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
static __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[N];
for(register int i=;i<=n;i++) {
p[i]=q.push((Vertex){i,dis[i]=i==s?:inf});
}
while(!q.empty()&&q.top().dis!=inf) {
const int x=q.top().id;
q.pop();
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to,&w=e[x][i].w;
if(dis[x]+w<dis[y]) {
q.modify(p[y],(Vertex){y,dis[y]=dis[x]+w});
}
}
}
while(!q.empty()) q.pop();
}
std::vector<int> top;
inline bool check() {
static int deg[N];
static std::queue<int> q;
memset(deg,,sizeof deg);
for(register int x=;x<=n;x++) {
for(register unsigned i=;i<e0[x].size();i++) {
const int &y=e0[x][i].to,&w=e0[x][i].w;
if(dis0[x]+w==dis0[y]) deg[y]++;
}
}
for(register int x=;x<=n;x++) {
if(!deg[x]) q.push(x);
}
while(!q.empty()) {
const int x=q.front();
q.pop();
top.push_back(x);
for(register unsigned i=;i<e0[x].size();i++) {
const int &y=e0[x][i].to,&w=e0[x][i].w;
if(dis0[x]+w!=dis0[y]) continue;
if(!--deg[y]) q.push(y);
}
}
for(register int x=;x<=n;x++) {
if(deg[x]&&dis0[x]+dis1[x]<=dis0[n]+lim) return false;
}
return true;
}
inline int calc() {
static int f[N][LIM];
memset(f,,sizeof f);
f[][]=;
for(register int k=;k<=lim;k++) {
for(register unsigned i=;i<top.size();i++) {
const int &x=top[i];
if(!f[x][k]) continue;
for(register unsigned i=;i<e0[x].size();i++) {
const int &y=e0[x][i].to,&w=e0[x][i].w;
if(dis0[x]+k+w<=dis0[y]+lim) {
(f[y][dis0[x]+k+w-dis0[y]]+=f[x][k])%=mod;
}
}
}
}
int ans=;
for(register int i=;i<=lim;i++) {
ans=(ans+f[n][i])%mod;
}
return ans;
}
inline void reset() {
for(register int i=;i<=n;i++) {
e0[i].clear();
e1[i].clear();
}
top.clear();
}
int main() {
for(register int T=getint();T;T--) {
n=getint(),m=getint(),lim=getint(),mod=getint();
while(m--) {
const int u=getint(),v=getint(),w=getint();
add_edge(u,v,w);
}
dijkstra(,dis0,e0);
dijkstra(n,dis1,e1);
printf("%d\n",check()?calc():-);
reset();
}
return ;
}

[NOIp2017提高组]逛公园的更多相关文章

  1. [NOIP2017 提高组] 逛公园

    考虑先做一个\(dp\),考虑正反建图,然后按0边拓扑,然后按1到这里的最小距离排序,然后扩展这个\(f_{i,j}\),即多了\(j\)的代价的方案数.

  2. [NOIp2017提高组]列队

    [NOIp2017提高组]列队 题目大意 一个\(n\times m(n,m\le3\times10^5)\)的方阵,每个格子里的人都有一个编号.初始时第\(i\)行第\(j\)列的编号为\((i-1 ...

  3. JZOJ 5196. 【NOIP2017提高组模拟7.3】B

    5196. [NOIP2017提高组模拟7.3]B Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits   Goto Pro ...

  4. JZOJ 5197. 【NOIP2017提高组模拟7.3】C

    5197. [NOIP2017提高组模拟7.3]C Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits   Goto Pro ...

  5. JZOJ 5195. 【NOIP2017提高组模拟7.3】A

    5195. [NOIP2017提高组模拟7.3]A Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits   Goto Pro ...

  6. JZOJ 5184. 【NOIP2017提高组模拟6.29】Gift

    5184. [NOIP2017提高组模拟6.29]Gift (Standard IO) Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed ...

  7. JZOJ 5185. 【NOIP2017提高组模拟6.30】tty's sequence

    5185. [NOIP2017提高组模拟6.30]tty's sequence (Standard IO) Time Limits: 1000 ms  Memory Limits: 262144 KB ...

  8. NOIP2017提高组 模拟赛15(总结)

    NOIP2017提高组 模拟赛15(总结) 第一题 讨厌整除的小明 [题目描述] 小明作为一个数学迷,总会出于数字的一些性质喜欢上某个数字,然而当他喜欢数字k的时候,却十分讨厌那些能够整除k而比k小的 ...

  9. NOIP2017提高组 模拟赛13(总结)

    NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...

随机推荐

  1. Android应用程序App应用上线流程

    对于很多初级开发者,可能对app应用上线不太了解,本文跟大家介绍一下怎么上线app应用.上线App并不是一件很困难的事情,App的应用功能也不需要很强大,甚至不用联网,只有简单的一两个页面的App应用 ...

  2. java封装示例代码

    package com.imooc; public class Telphone { private float screen; private float cpu; private float me ...

  3. Python模块学习 - ConfigParser

    配置文件 很多软件都用到了配置文件,像git运行的时候会读取~/gitconfig,MySQL运行的时候会读取/etc/my.cnf,Python 提供的包管理工具pip命令,也会去读取~/.pip/ ...

  4. SQL语句语法简介

    SQL命令一般分为DQL.DML.DDL几类: DQL:数据查询语句,基本就是SELECT查询命令,用于数据查询 DML:Data Manipulation Language的简称,即数据操纵语言,主 ...

  5. Linux中查看进程占用内存的情况【转】

    转自:http://hutaow.com/blog/2014/08/28/display-process-memory-in-linux/ Linux中查看某个进程占用内存的情况,执行如下命令即可,将 ...

  6. Linux 入门记录:二、Linux 文件系统基本结构

    一.树状目录结构 Linux 文件系统是一个倒置的单根树状结构.文件系统的根为"/":文件名严格区分大小写:路径使用"/"分割(Windows 中使用" ...

  7. charger related source code position

    Platform Qualcomm MSM8917 or MSM8937 Source kernel/msm-3.18/drivers/power/qpnp-smbcharger.c kernel/m ...

  8. 从LFS官方文档构建完整Linux系统

    从LFS官方文档构建完整Linux系统 http://www.cnblogs.com/sonofdark/p/4962609.html 这不是新手教程!!! Parallels Desktop (为防 ...

  9. 20:django中的安全问题

    本节主要是讲解django中的安全特性,讲述django是如何应对网站一般面临的安全性问题 跨站点脚本(XXS)攻击 跨站点脚本攻击是指一个用户把客户端脚本注入到其他用户的浏览器中.通常是通过在数据库 ...

  10. http跟https的区别

    http: Hypertext transform protocol 超文本传输协议 是一个为了传输超媒体文档(比如html)的应用层协议 是为了web的浏览器跟web的server端的交流而设计的, ...