[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 ...
随机推荐
- spring mvc 提供的几个常用的扩展点
转载 :http://blog.csdn.net/gufachongyang02/article/details/43836105 这是spring3 mvc的核心流程图: SpirngMVC的第 ...
- 4.FireDAC组件快照 二
TFDUpdateSQL 生成添加,删除,修改SQL语句 TFDMetaInfoQuery 查询数据源信息 TFDEventAlerter 负责处理数据库事件通知 使用TFDEventAlerter类 ...
- 【Spring事务的事务属性】
大家都知道,Spring的声明式事务是通过事务属性来定义的,而spring的事务属性包含了5个方面:传播行为,隔离级别,是否只读,事务超时,回滚规则: 传播行为 传播行为,是属于事务边界相关的属性,定 ...
- POJ 1456 Supermarket(贪心+并查集)
题目链接:http://poj.org/problem?id=1456 题目大意:有n件商品,每件商品都有它的价值和截止售卖日期(超过这个日期就不能再卖了).卖一件商品消耗一个单位时间,售卖顺序是可以 ...
- Servlet的监听器Listener
Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是 随web应用的启动而启动,只初始化一次,随web ...
- gradle eclipse 配置
http://blog.csdn.net/caolaosanahnu/article/details/17022321 从gradle官网下载 解压,配置环境变量,gradle -v 验证 gradl ...
- hdu 2768(建图,最大点独立集)
Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- linux下输入密码不回显
这几天在做一个登陆的程序,需要将输入的密码屏蔽掉,自己百度,找到了两种方法,先贴下第一种方法, #include<stdio.h> #include<unistd.h> int ...
- SGU 261. Discrete Roots
给定\(p, k, A\),满足\(k, p\)是质数,求 \[x^k \equiv A \mod p\] 不会... upd:3:29 两边取指标,是求 \[k\text{ind}_x\equiv ...
- .net 多播委托的使用方法以及场景,更简单的观察者模式
首先来说一下什么是多播委托 多播委托就是在委托里定义一个或者多个方法的一个集合 使用方法: public Action actList; //添加方法 public void AddActionMet ...