题目大意:
  给你一个有向图,若用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. python2 处理urllib/urllib2错误并打印源码

    import urllib2 import urllib url = 'http://localhost/12.php' data = {} data['cmd']='whoami' data = u ...

  2. python自动开发之第二十二天

    知识点概要 - Session - CSRF - Model操作 - Form验证(ModelForm) - 中间件 - 缓存 - 信号 一. Session 基于Cookie做用户验证时:敏感信息不 ...

  3. TCP之Nagle算法与延迟ACK

    (一)Nagle算法 为了减少网络中小分组的数目,减少网络拥塞的情况.Nagle算法要求在一条TCP连接上最多只能有一个未被确认的未完成小分组,在该分组ACK到达之前不能够发送其他的小分组,发送端需要 ...

  4. canvas画画板,canvas画五角星,canvas制作钟表、Konva写钟表

    制作一个画画板,有清屏有橡皮擦有画笔可以换颜色 style样式 <head> <meta charset="UTF-8"> <title>画画板 ...

  5. [总结]可重用cell的定义方式

    1.简介 为了提高tableview中cell的加载速度通常可以使用cell重用的方式来实现,即我们向上拖动cell的时候,上部份消失的cell可以重复的被下部分出现的cell重用. 2.说明 一般c ...

  6. DNS解析原理与Bind部署DNS服务

    DNS是什么? DNS(Domain Name System,域名系统)是互联网上最核心的带层级的分布式系统,它负责把域名转换为IP地址.反查IP到域名的反向解析以及宣告邮件路由等信息,使得基于域名提 ...

  7. mycncart自定义主题

    本文是自己通过其他主题,自学的,如果有什么问题,可以提出建议? 参考资料:opencart官网 www.opencart.com  或 mycncart的官网上的一些教程 www.mycncart.c ...

  8. LeetCode解题报告—— 1-bit and 2-bit Characters & 132 Pattern & 3Sum

    1. 1-bit and 2-bit Characters We have two special characters. The first character can be represented ...

  9. hdu 2044-2050 递推专题

    总结一下做递推题的经验,一般都开成long long (别看项数少,随便就超了) 一般从第 i 项开始推其与前面项的关系(动态规划也是这样),而不是从第i 项推其与后面的项的关系. hdu2044:h ...

  10. AC日记——【模板】分块/带修改莫队(数颜色) 洛谷 P1903

    [模板]分块/带修改莫队(数颜色) 思路: 带修改莫队: (伏地膜xxy): 代码: #include <bits/stdc++.h> using namespace std; #defi ...