The main idea is to give a diagram, and then give a starting point for an end, the two points between the K short.
In this case, it is possible to repeat the road, so if there is a ring in a picture, no matter what the first few short-circuiting are present.
Most of the methods on the Internet are made with a * + short-circuit method.
For a *, the valuation function = The current value + the distance from the current position to the end point, i.e. F (p) =g (P) +h (p), each extending the smallest of the valuation function values. For a k short circuit, g (p) is the length of the current from S to P, H (p) is the shortest length from p to T, the meaning of F (p) is to go to the end of the current path from S to p and at least how far to go. In other words, each extension is a directional extension, which increases the speed of the solution and reduces the number of states that are expanding. To accelerate the calculation, H (p) needs to be pre-preprocessed from a A * search, so long as all the edges of the original image are reversed, and then the single-source shortest path from the endpoint T can get H (p) for each point.
In the following code
In a struct, V represents the current point, F and G are the values of the F function and the G function, and the F function is smaller each time it is first searched. This will ensure that the search comes out must be the K small short circuit, and to avoid a certain need to calculate.
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue&
Gt
#define MAXN 1005 #define MAXM 500005 #define INF 1000000000 using namespace std; struct Node {int V, W, next;}
EDGE[MAXM], REVEDGE[MAXM];
struct A {int F, G, V;
BOOL operator < (const a a) const {if (A.F = = f) return A.G < G;
return A.F < F;
}
};
int e, VIS[MAXN], D[MAXN], Q[MAXM * 5];
int HEAD[MAXN], REVHEAD[MAXN];
int N, m, S, T, K;
void Init () {e = 0;
Memset (Head,-1, sizeof (head));
memset (Revhead,-1, sizeof (revhead));
} void Insert (int x, int y, int w) {edge[e].v = y;
EDGE[E].W = W;
Edge[e].next = Head[x];
HEAD[X] = e;
REVEDGE[E].V = x;
REVEDGE[E].W = W;
Revedge[e].next =revhead[y];
Revhead[y] = e++;
} void Spfa (int src) {for (int i = 1; I <= n; i++) d[i] = INF;
memset (Vis, 0, sizeof (VIS));
VIS[SRC] = 0;
int h = 0, t = 1;
Q[0] = src;
D[SRC] = 0; while (H < t) {int u = q[h++];
Vis[u] = 0;
for (int i = revhead[u]; i =-1; i = revedge[i].next) {int v = REVEDGE[I].V;
int w = REVEDGE[I].W;
if (D[v] > D[u] + W) {D[v] = D[u] + W;
if (!vis[v]) {q[t++] = V;
VIS[V] = 1;
}}}}} int Astar (int src, int des) {int cnt = 0;
priority_queue<a>q;
if (src = = des) k++;
if (d[src] = = INF) return-1;
A T, TT;
T.V = src, t.g = 0, T.f = t.g + D[SRC];
Q.push (t); while (!
Q.empty ()) {TT = Q.top ();
Q.pop ();
if (tt.v = = des) {cnt++;
if (cnt = = k) return TT.G;
} for (int i = HEAD[TT.V]; i =-1; i = edge[i].next) {T.V = EDGE[I].V;
T.G = tt.g + edge[i].w;
T.F = T.g + D[T.V]; Q.push (t);
}} return-1;
} int main () {int x, y, W;
while (scanf ("%d%d", &n, &m)! = EOF) {init ();
for (int i = 1; I <= m; i++) {scanf ("%d%d%d", &x, &y, &w);
Insert (x, Y, W);
} scanf ("%d%d%d", &s, &t, &k);
SPFA (t);
printf ("%d\n", Astar (S, t));
} return 0;
}