这个题就是让你求出S点到T点的第K短路, 使用A*搜索就可以, 搜索使用两个指标函数 h g, h表示从源点到当前点的最短路, g点表示从当前点到汇点的最短路, 搜索的时候v顶点第k次出队时的h就是第k短路的长度, 代码如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <vector> using namespace std; const int maxn = 1000 + 10; int N, M; int S, T, K; struct edge { int v, c; }; vector<edge> G[maxn]; //正向边 vector<edge> P[maxn]; //反向边 int g[maxn]; //求解出h函数的值 struct Dij { int u, c; bool operator<(const Dij&r) const { return c>r.c; } }; bool vis[maxn]; void dijkstra(int s) { memset(g, 0x3f, sizeof(g)); g[s] = 0; memset(vis, 0, sizeof(vis)); priority_queue<Dij> que; que.push((Dij){s, 0}); while(!que.empty()) { Dij tp = que.top(); que.pop(); int u=tp.u; if(vis[u]) continue; vis[u] = 1; for(int i=0; i<P[u].size(); i++) { int v = P[u][i].v, cost = P[u][i].c; if(g[v] > g[u]+cost) { g[v] = g[u]+cost; que.push((Dij){v, g[v]}); } } } } struct Astar { int h, g, u; bool operator< (const Astar& r) const { return h+g > r.h+r.g; } }; int times[maxn]; int astar() { memset(times, 0, sizeof(times)); priority_queue<Astar> que; que.push((Astar){0, g[S], S}); if(S == T) K++; while(!que.empty()) { Astar tp = que.top(); que.pop(); int u = tp.u; times[u]++; if(times[u]==K && u==T) return tp.h; else if(times[u] > K) continue; for(int i=0; i<G[u].size(); i++) { int v = G[u][i].v, c=G[u][i].c; que.push((Astar){tp.h+c, g[v], v}); } } return -1; } int main() { scanf("%d%d", &N, &M); for(int i=0; i<M; i++) { int u, v, t; scanf("%d%d%d", &u, &v, &t); G[u].push_back((edge){v, t}); P[v].push_back((edge){u, t}); } scanf("%d%d%d", &S, &T, &K); dijkstra(T); int res = astar(); printf("%d\n", res); return 0; }
时间: 2024-10-29 19:12:17