A* + dijkstra(heap)
#include
<
iostream
>
#include
<
vector
>
#include
<
queue
>
#include
<
algorithm
>
using
namespace
std;
#define
MAXN 1001
#define
INF 0x7f7f7f7f
typedef pair
<
int
,
int
>
PAIR;
//
typedef make_pair MP;
int
dist[MAXN],n,m,S,T,K,cnt[MAXN];
vector
<
PAIR
>
map1[MAXN],map2[MAXN];
struct
path{
int
v,g;
path(){};
path(
int
a,
int
b):v(a),g(b){}
};
void
dijkstra(){
int
i,u,len,v,cost;
priority_queue
<
PAIR,vector
<
PAIR
>
,greater
<
PAIR
>
>
qu;
//
最小堆
//
priority_queue<PAIR> qu;
//
最大堆
memset(dist,
0x7f
,
sizeof
(dist));
dist[T]
=
0
;
qu.push(make_pair(
0
,T));
while
(
!
qu.empty()){
u
=
qu.top().second;
len
=
qu.top().first;
qu.pop();
if
(dist[u]
!=
len)
//
该路径并不是局部最短路,故不作扩展
continue
;
for
(i
=
0
;i
<
map1[u].size();i
++
){
v
=
map1[u][i].second;
cost
=
map1[u][i].first;
if
(dist[v]
>
dist[u]
+
cost){
dist[v]
=
dist[u]
+
cost;
qu.push(make_pair(dist[v],v));
}
}
}
}
class
CP{
public
:
int
operator
()(path
&
a,path
&
b){
return
a.g
+
dist[a.v]
>
b.g
+
dist[b.v];
//
最小堆
}
};
int
astar(){
int
i,v,cost,len;
memset(cnt,
0
,
sizeof
(cnt));
priority_queue
<
path,vector
<
path
>
,CP
>
qu;
if
(S
==
T)
K
++
;
if
(dist[S]
==
INF)
return
-
1
;
qu.push(path(S,
0
));
while
(
!
qu.empty()){
v
=
qu.top().v;
len
=
qu.top().g;
qu.pop();
cnt[v]
++
;
if
(cnt[T]
==
K)
return
len;
if
(cnt[v]
>
K)
//
若v是S到T的K短路上的一点,则cnt[v]不可能大于K,否则已至少有从S到T的cnr[v]-1条比现计划路径短的路径,与v是S到T的K短路上的一点矛盾
continue
;
for
(i
=
0
;i
<
map2[v].size();i
++
)
qu.push(path(map2[v][i].second,len
+
map2[v][i].first));
}
return
-
1
;
}
int
main(){
int
i,x,y,d;
scanf(
"
%d%d
"
,
&
n,
&
m);
for
(i
=
0
;i
<
m;i
++
){
scanf(
"
%d%d%d
"
,
&
x,
&
y,
&
d);
map1[y].push_back(make_pair(d,x));
map2[x].push_back(make_pair(d,y));
}
scanf(
"
%d%d%d
"
,
&
S,
&
T,
&
K);
dijkstra();
printf(
"
%d\n
"
,astar());
return
0
;
}