luogu3953 [NOIp2017]逛公园 (tarjan+dijkstra+记忆化搜索)
先跑一边dijkstra算出从1到i的最短距离dis[i]
然后建反向边 从n开始记忆化搜索,(p,k)表示1到p的距离=dis[p]+k的方案数
答案就是$\sum\limits_{i=0}^{k}{(n,i)}$
考虑0环,如果我记搜的时候搜到了0环,那答案就是-1,可以先用tarjan处理一下0边 看看有哪些点在零环上
(其实也可以开个栈 做到(p,k)的时候看(p,k)是不是已经在栈中了 如果是那就是-1)
#include<bits/stdc++.h>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
const int maxn=1e5+,maxm=2e5+,maxk=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} struct Edge{
int b,l,ne;
}eg[maxm],neg[maxm];
struct Node{
int p,k,n;
Node(int a=,int b=,int c=){p=a,k=b,n=c;}
};
int egh[maxn],negh[maxn],ect,nect;
int dis[maxn],f[maxn][maxk];
int dfn[maxn],tot,low[maxn],stk[maxn],sh;
int N,M,K,P;
bool in0[maxn],instk[maxn],flag[maxn]; inline void adeg(int a,int b,int c){
eg[++ect].b=b,eg[ect].l=c,eg[ect].ne=egh[a],egh[a]=ect;
neg[++nect].b=a,neg[nect].l=c,neg[nect].ne=negh[b],negh[b]=nect;
} void tarjan(int x){
dfn[x]=low[x]=++tot,instk[x]=,stk[++sh]=x;
for(int i=egh[x];i;i=eg[i].ne){
if(eg[i].l) continue;
int b=eg[i].b;
if(!dfn[b]) tarjan(b),low[x]=min(low[x],low[b]);
else if(instk[b]) low[x]=min(low[x],dfn[b]);
}
if(dfn[x]==low[x]){
int n=;
for(int i=sh;stk[i]!=x;i--) n++;
while(){
instk[stk[sh]]=;
in0[stk[sh]]=n>;
if(stk[sh--]==x) break;
}
}
} priority_queue<pa,vector<pa>,greater<pa> > q;
inline void dijkstra(){
while(!q.empty()) q.pop();
CLR(flag,);CLR(dis,);dis[]=;
q.push(make_pair(,));
while(!q.empty()){
int p=q.top().second;q.pop();
if(flag[p]) continue;
flag[p]=;
for(int i=egh[p];i;i=eg[i].ne){
int b=eg[i].b;
if(dis[b]>dis[p]+eg[i].l){
dis[b]=dis[p]+eg[i].l;
q.push(make_pair(dis[b],b));
}
}
}
} inline int solve(int x,int y){
// if(f[x][y]>=0) printf("get%d %d %d\n",x,y,f[x][y]);
if(y<||y>K) return ;
if(in0[x]) return -;
if(f[x][y]>=) return f[x][y];
f[x][y]=;
for(int i=negh[x];i;i=neg[i].ne){
int b=neg[i].b;
int re=solve(b,dis[x]-dis[b]+y-neg[i].l);
if(re==-) return -;
f[x][y]+=re,f[x][y]%=P;
}
return f[x][y];
} int main(){
int i,j,k;
for(int T=rd();T;T--){
N=rd(),M=rd(),K=rd(),P=rd();
CLR(egh,);ect=;
CLR(negh,);nect=;
for(i=;i<=M;i++){
int a=rd(),b=rd(),c=rd();
adeg(a,b,c);
}
CLR(dfn,);CLR(instk,);tot=;CLR(in0,);
for(i=;i<=N;i++)
if(!dfn[i]) tarjan(i);
dijkstra();
CLR(f,-);
f[][]=;int ans=;
for(i=;i<=K;i++)
ans+=solve(N,i),ans%=P;
printf("%d\n",ans<?-:ans);
} return ;
}
luogu3953 [NOIp2017]逛公园 (tarjan+dijkstra+记忆化搜索)的更多相关文章
- Luogu P3953 逛公园(最短路+记忆化搜索)
P3953 逛公园 题面 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园的入口,\(N\) 号点是公 ...
- HDU1142 (Dijkstra+记忆化搜索)
A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...
- Luogu 3953[NOIP2017] 逛公园 堆优化dijkstra + 记忆化搜索
题解 首先肯定是要求出单源最短路的,我用了堆优化dijikstra ,复杂度 mlogm,值得拥有!(只不过我在定义优先队列时把greater 打成了 less调了好久 然后我们就求出了$i$到源点的 ...
- HDU 1142 A Walk Through the Forest(Dijkstra+记忆化搜索)
题意:看样子很多人都把这题目看错了,以为是求最短路的条数.真正的意思是:假设 A和B 是相连的,当前在 A 处, 如果 A 到终点的最短距离大于 B 到终点的最短距离,则可以从 A 通往 B 处,问满 ...
- 【UVA11324】 The Largest Clique (Tarjan+topsort/记忆化搜索)
UVA11324 The Largest Clique 题目描述 给你一张有向图 \(G\),求一个结点数最大的结点集,使得该结点集中的任意两个结点 \(u\) 和 \(v\) 满足:要么 \(u\) ...
- 洛谷 P3953 逛公园【spfa+记忆化dfs+bfs】
spfa预处理出最短路数组dis,然后反向建边bfs出ok[u]表示u能到n点 然后发现有0环的话时候有inf解的,先dfs找0环判断即可 然后dfs,设状态f[u][v]为到u点,还可以跑最短路+v ...
- Luogu3953 NOIP2017逛公园(最短路+拓扑排序+动态规划)
跑一遍dij根据最短路DAG进行拓扑排序,按拓扑序dp即可.wa了三发感觉非常凉. #include<iostream> #include<cstdio> #include&l ...
- 逛公园 [NOIP2017 D1T3] [记忆化搜索]
Description 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花的 ...
- 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索
题目描述 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策 ...
随机推荐
- semantic-ui 分段
分段:用于创建一组相关联的内容. 1.创建一个基础的分段 在class中加一个segment的class即可 <div class="ui segment"> < ...
- MySQL中关于数据类型指定宽度之后的情况
概述 MySQL有很多种数据类型,最常用的就是int,char,varchar,这些类型在创建表的时候都可以指定该字段的宽度,方法是在类型后面加一个括号,括号中写宽度就可以了. 但是,在指定宽度之后, ...
- 【转】Docker部署Tomcat及Web应用
Docker部署Tomcat及Web应用 - Scofield_No1的博客 - CSDN博客https://blog.csdn.net/qq_32351227/article/details/786 ...
- 【转帖】Linux的历史----Linux内核剖析(一)
Linux的历史----Linux内核剖析(一) 2015年04月09日 10:51:09 JeanCheng 阅读数:11351更多 所属专栏: Linux内核剖析 版权声明:本文为博主原创文 ...
- [转帖]TCP和UDP的135、137、138、139、445端口的作用
TCP和UDP的135.137.138.139.445端口的作用 https://www.cnblogs.com/IvanChen/p/4500698.html 竟然不知道 端口具体是干什么的.. 如 ...
- python爬虫之scrapy模拟登录
背景: 初来乍到的pythoner,刚开始的时候觉得所有的网站无非就是分析HTML.json数据,但是忽略了很多的一个问题,有很多的网站为了反爬虫,除了需要高可用代理IP地址池外,还需要登录.例如知乎 ...
- java学习之—栈匹配字符串符号
/** * 栈 * Create by Administrator * 2018/6/11 0011 * 上午 10:20 **/ public class StackR { private int ...
- Java8 flatMap的sample
外国人写得, 很不错 http://www.java67.com/2016/03/how-to-use-flatmap-in-java-8-stream.html package test; impo ...
- No module named 'ConfigParser'
系统: CentOS-6.4-x86_64 Python : Python 3.4.5 和 Python 3.5.2 安装 MySQL-python ,结果出错: ImportError: No mo ...
- Python memecache
memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载,故常用来做数据库缓存.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态 ...