k
k
k短路模板。
k
k
k短路算法大致流程(
A
∗
A^*
A∗):
以下
S
S
S为起点,
T
T
T为终点,
a
→
b
a \rightarrow b
a→b表示从
a
a
a到
b
b
b这条路径的长度。
①反向图跑一个最短路求出每个点到终点最短距离
d
i
s
[
u
]
dis[u]
dis[u]。
②正向图
b
f
s
bfs
bfs,每扩展到一个点
v
v
v,就把
n
o
d
e
(
v
,
S
→
v
)
node(v,S \rightarrow v)
node(v,S→v)加入优先队列,优先队列按照
S
→
v
+
d
i
s
[
v
]
S \rightarrow v+dis[v]
S→v+dis[v]从小到大排序。
③当第
i
i
i次从优先队列中取出点
u
u
u时,如果此时的
S
→
u
=
w
S \rightarrow u=w
S→u=w,那么
w
w
w即为
S
→
u
S \rightarrow u
S→u的第
i
i
i短路长度。于是当
T
T
T第
k
k
k次被取出时,对应记录的
S
→
T
S \rightarrow T
S→T距离即为
k
k
k短路长度。
d
i
j
k
s
t
r
a
dijkstra
dijkstra相当于是估值函数
d
i
s
dis
dis全为
0
0
0,并且只求第
1
1
1短。当一个点被取出
k
k
k次时,后面的扩展到它的路径就不可能在
k
k
k短路里了。
#include<bits/stdc++.h>
#define fi first
#define cs const
#define se second
#define re register
#define mp std::make_pair
#define pdi std::pair<double,int>
int n,m,u,v;double E,w;
namespace GRAPH{
cs int N=5e3+10,M=2e5+10;
int Head[N],Next[M],V[M],cnt=0;double W[M];
int vis[N],rHead[N],rNext[M],rV[M],rcnt=0;double rW[M];
double dis[N];
inline void add(int u,int v,double w){Next[++cnt]=Head[u],V[cnt]=v,W[cnt]=w,Head[u]=cnt;}
inline void radd(int u,int v,double w){rNext[++rcnt]=rHead[u],rV[rcnt]=v,rW[rcnt]=w,rHead[u]=rcnt;}
inline void dijkstra(int S){
memset(dis,127,sizeof dis);
std::priority_queue<pdi> Q;
Q.push(mp(0,S)),dis[S]=0;
while(!Q.empty()){
int u=Q.top().se;Q.pop();
for(int re i=rHead[u],v=rV[i];i;v=rV[i=rNext[i]])
if(dis[v]>dis[u]+rW[i]) dis[v]=dis[u]+rW[i],Q.push(mp(-dis[v],v));
}
}
struct node{
int u;double d;
node(int U=0,double D=0){u=U,d=D;}
friend inline bool operator<(cs node &a,cs node &b)
{return a.d+dis[a.u]>b.d+dis[b.u];}
};
inline int Astar(int S,int T,int ans=0){
std::priority_queue<node> Q;Q.push(node(S,0));
while(!Q.empty()){
node U=Q.top();Q.pop();
if(U.u==T){
if(E>U.d) E-=U.d,++ans;
else return ans;
continue;
}
for(int re i=Head[U.u],v=V[i];i;v=V[i=Next[i]])
Q.push(node(v,U.d+W[i]));
}
}
}
using namespace GRAPH;
int main(){
// freopen("3056.in","r",stdin);
scanf("%d%d%lf",&n,&m,&E);
while(m--) scanf("%d%d%lf",&u,&v,&w),add(u,v,w),radd(v,u,w);
dijkstra(n),printf("%d\n",Astar(1,n));
}