[NOIp2017提高组]逛公园
题目大意:
给你一个有向图,若用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提高组]逛公园的更多相关文章
- [NOIP2017 提高组] 逛公园
考虑先做一个\(dp\),考虑正反建图,然后按0边拓扑,然后按1到这里的最小距离排序,然后扩展这个\(f_{i,j}\),即多了\(j\)的代价的方案数.
- [NOIp2017提高组]列队
[NOIp2017提高组]列队 题目大意 一个\(n\times m(n,m\le3\times10^5)\)的方阵,每个格子里的人都有一个编号.初始时第\(i\)行第\(j\)列的编号为\((i-1 ...
- JZOJ 5196. 【NOIP2017提高组模拟7.3】B
5196. [NOIP2017提高组模拟7.3]B Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits Goto Pro ...
- JZOJ 5197. 【NOIP2017提高组模拟7.3】C
5197. [NOIP2017提高组模拟7.3]C Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits Goto Pro ...
- JZOJ 5195. 【NOIP2017提高组模拟7.3】A
5195. [NOIP2017提高组模拟7.3]A Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits Goto Pro ...
- JZOJ 5184. 【NOIP2017提高组模拟6.29】Gift
5184. [NOIP2017提高组模拟6.29]Gift (Standard IO) Time Limits: 1000 ms Memory Limits: 262144 KB Detailed ...
- 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 ...
- NOIP2017提高组 模拟赛15(总结)
NOIP2017提高组 模拟赛15(总结) 第一题 讨厌整除的小明 [题目描述] 小明作为一个数学迷,总会出于数字的一些性质喜欢上某个数字,然而当他喜欢数字k的时候,却十分讨厌那些能够整除k而比k小的 ...
- NOIP2017提高组 模拟赛13(总结)
NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...
随机推荐
- sublime在搜索的时候排除js文件
代码审计的时候sublime是一个神器.所以.... Ctrl + Shift + F /home/i3ekr/Desktop/coding/phpcms,*.php 这样就可以直接搜索所有的php文 ...
- vue-实现倒计时功能
JavaScript 创建一个 countdown 方法,用于计算并在控制台打印距目标时间的日.时.分.秒数,每隔一秒递归执行一次. msec 是当前时间距目标时间的毫秒数,由时间戳相减得到,我们将以 ...
- tex src
https://github.com/jepsonr/Text-Exercises https://github.com/Khan/KaTeX https://github.com/goldsboro ...
- 3.FireDAC组件快照
TFDManager 连接定义和Connect连接管理 TFDConnection 数据库连接组件,支持三种连接方式:1.持久定义(有一个唯一名称和一个配置文件,可以由FDManager管理) 例: ...
- NOIP 2011 Day2
tags: 贪心 模拟 NOIP categories: 信息学竞赛 总结 计算系数 Solution 根据二项式定理, \[ \begin{align} (a+b)^n=\sum_{k=0}^nC_ ...
- mac date命令
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd ...
- iOS---弹出提示对话框
一.就一个选项的对话框 代码块 #pragma mark - 封装弹出对话框方法 // 提示错误信息 - (void)showError:(NSString *)errorMsg { // 1.弹框提 ...
- 【mongo】启动mongo
输入mongo应该就可以启动了.但是我得到了一个报错信息. Failed global initialization: BadValue Invalid or no user locale set. ...
- hadoop3.1 ha高可用部署
1.资源角色规划
- SGU 261. Discrete Roots
给定\(p, k, A\),满足\(k, p\)是质数,求 \[x^k \equiv A \mod p\] 不会... upd:3:29 两边取指标,是求 \[k\text{ind}_x\equiv ...