[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 ...
随机推荐
- for in、each; for 、forEach、map
1.jQuery.each(object, [callback]) 用于例遍任何对象.回调函数拥有两个参数:第一个为对象的成员或数组的索引,第二个为对应变量或内容.如果需要退出 each 循环可使回调 ...
- ARM中断向量表与响应流程【转】
转自:http://blog.csdn.net/honour2sword/article/details/40213417 一首先中断向量表定义在哪里?如何加载? 二 中断向量表与中断服务程序 三处理 ...
- monkey测试===easyMonkey测试【推荐】
easymonkey测试: easymonkey是基于monkey测试的一个二次开发工具.(关于monkey测试参见之前blog) easymonkey的特点就是方便,解决了很多参数命令上设置的麻烦, ...
- Android内存溢出解决方案总结
我的视频会议中有三个内存泄露的崆点: 1) BNLiveControlView mView = this; 未释放 (自定义view中自己引用自己造成) 2) 在自定义View中区注册了系统的网络变化 ...
- goreplay HTTP-HTTPS流量复制工具
goreplay相比tcpcopy只能复制HTTP和HTTPS的流量 goreplay编译很麻烦,就直接使用编译好的版本 gor_0.10.1_x64.tar.gz 支持centos5,测试的是cen ...
- 在Xcode中使用自定义的代码片段提高效率
拖动代码的时候按住option键,很难拖,注意方法:< 引用于:http://www.2cto.com/kf/201409/336245.html
- nowcoder 提高第六场A题
Solution 60分 因为所有的字母要么全相同要么全不同, 所以两条路径比较字典序只需要比较第一条边就可以, 于是建反图, 在反图上按拓扑序转移就可以. 因为有环, 所以拓扑完入度还是不为0的点答 ...
- django “如何”系列6:如何部署django
django满满的快捷方法是的web开发者活的更轻松,但是,如果你不能部署你的站点的话,这是一点用都没有的.不违初衷,部署的简化也是django的一大目标.你可以有几个方法轻松的部署django 由于 ...
- LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku
1. Search in Rotated Sorted Array Suppose an array sorted in ascending order is rotated(轮流,循环) at so ...
- Jenkins发布PHP代码
实验环境 10.0.0.12 Jenkins服务器 10.0.0.13 远程服务器 一个远程的公开的git仓库(php代码在这个仓库里) 一.检查插件是否安装并安装插件 在通过Jenkins发布php ...