先跑一边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+记忆化搜索)的更多相关文章

  1. Luogu P3953 逛公园(最短路+记忆化搜索)

    P3953 逛公园 题面 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园的入口,\(N\) 号点是公 ...

  2. HDU1142 (Dijkstra+记忆化搜索)

    A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  3. Luogu 3953[NOIP2017] 逛公园 堆优化dijkstra + 记忆化搜索

    题解 首先肯定是要求出单源最短路的,我用了堆优化dijikstra ,复杂度 mlogm,值得拥有!(只不过我在定义优先队列时把greater 打成了 less调了好久 然后我们就求出了$i$到源点的 ...

  4. HDU 1142 A Walk Through the Forest(Dijkstra+记忆化搜索)

    题意:看样子很多人都把这题目看错了,以为是求最短路的条数.真正的意思是:假设 A和B 是相连的,当前在 A 处, 如果 A 到终点的最短距离大于 B 到终点的最短距离,则可以从 A 通往 B 处,问满 ...

  5. 【UVA11324】 The Largest Clique (Tarjan+topsort/记忆化搜索)

    UVA11324 The Largest Clique 题目描述 给你一张有向图 \(G\),求一个结点数最大的结点集,使得该结点集中的任意两个结点 \(u\) 和 \(v\) 满足:要么 \(u\) ...

  6. 洛谷 P3953 逛公园【spfa+记忆化dfs+bfs】

    spfa预处理出最短路数组dis,然后反向建边bfs出ok[u]表示u能到n点 然后发现有0环的话时候有inf解的,先dfs找0环判断即可 然后dfs,设状态f[u][v]为到u点,还可以跑最短路+v ...

  7. Luogu3953 NOIP2017逛公园(最短路+拓扑排序+动态规划)

    跑一遍dij根据最短路DAG进行拓扑排序,按拓扑序dp即可.wa了三发感觉非常凉. #include<iostream> #include<cstdio> #include&l ...

  8. 逛公园 [NOIP2017 D1T3] [记忆化搜索]

    Description 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花的 ...

  9. 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索

    题目描述 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策 ...

随机推荐

  1. redux模块化demo

    store.js 在redux中 store 是唯一的. import {createStore} from 'redux'; import reducer from './reducer' // 引 ...

  2. CLOUD添加自定义基础数据

    1.打开bos平台,文件-新建-复制-基础资料 2.新建目标对象 3.发布 4.开始新增对象 5.明细维护,完成 6.添加成功

  3. Codeforces 1154G Minimum Possible LCM

    题目链接:http://codeforces.com/problemset/problem/1154/G 题目大意: 给定n个数,在这些数中选2个数,使这两个数的最小公倍数最小,输出这两个数的下标(如 ...

  4. shiro使用ajax登陆实现,success但页面无法跳转的问题

    首先:简述一下登陆的后台流程 页面提交——>对应controller中的方法——>对应Realm认证——>controller返回 json 这样,无论成功与否,都有返回值,可以用 ...

  5. BugFree 安装

    BugFree基于PHP和MySQL开发,是免费且开发源代码的缺陷管理系统.服务器端在Linux和Windows平台上都可以运行:客户端无需安装任何软件,通过IE,FireFox等浏览器就可以自由使用 ...

  6. 循环神经网络RNN及LSTM

    一.循环神经网络RNN RNN综述 https://juejin.im/entry/5b97e36cf265da0aa81be239 RNN中为什么要采用tanh而不是ReLu作为激活函数?  htt ...

  7. oracle ceil函数

    ceil和floor函数在一些业务数据的时候,有时还是很有用的. ceil(n) 取大于等于数值n的最小整数: floor(n)取小于等于数值n的最大整数 如下例子 SQL> select ce ...

  8. Python介绍及环境配置

    Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有 ...

  9. luogu P1077 摆花

    这道题看似好难,但是其实很简单 先把题目中所让你设的变量都设好,该输入的都输入 你会发现这道题好像成功了一半,为什么呢??? 因为设完后你会发现你不需要再添加任何变量,已经足够了. 可能最难的地方,就 ...

  10. BZOJ3291Alice与能源计划——匈牙利算法+模拟费用流

    题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验.为 了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...