第K短路(模板)
没太想明白(就当存在模板吧)
#include<bits/stdc++.h> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <stack> #include <vector> using namespace std; typedef long long LL; const int Maxn = 1e5 + 7; const int Inf = 1e9 + 7; int N, M, K; int start, End; int ans; //最短路部分 int dis[Maxn]; bool vis[Maxn]; struct node { int v, w; friend bool operator < (node a, node b) { return a.w > b.w; } }; /* * A* 启发式搜索函数 F[x] = H[x] + G[x] * 变量 Hx 表示搜索到当前点 所用的代价 * 变量 Gx 是估价函数 (估价函数要小于等于实际值,否则出错) */ struct edge { int v, Hx, Gx; friend bool operator < (edge a, edge b) { return a.Hx + a.Gx > b.Hx + b.Gx; } }; /* * count 记录第几次BFS拓展到此点 * 当 count == K 时 不再对此点继续进行拓展(因为拓展的点必定大于 第K短路) */ int Count[Maxn]; vector <node> G[Maxn], G2[Maxn]; /* * (因为是有向图所以反向建图) * 求End到每个点的最短路 */ void Dijkstra() { memset(vis,0,sizeof(vis)); memset(dis,Inf,sizeof(dis)); priority_queue <node> que; que.push({End, 0}); dis[End] = 0; node q; int v, w; while(!que.empty()){ int v = que.top().v; que.pop(); if(vis[v]) continue; vis[v] = true; int _size=G2[v].size(); for(int i = 0 ; i < _size ; i++){ node now=G2[v][i]; if(dis[now.v] > dis[v]+now.w){ dis[now.v] = dis[v]+now.w; que.push({now.v,dis[now.v]}); } } } } /* * 第K短路算法 = A* + BFS */ void Astar(){ ans = -1; memset(Count,0,sizeof(Count)); priority_queue <edge> que; que.push({start, 0, 0}); edge q; int v, Hx, Gx; while(!que.empty()){ q = que.top(); que.pop(); v = q.v, Hx = q.Hx, Gx = q.Gx; Count[v]++; if(Count[v] == K && v == End){ ans = Hx + Gx; break; } if(Count[v] > K) continue; int to, hx, gx; int _size=G[v].size(); for(int i = 0 ; i < _size ; i++) { to = G[v][i].v; hx = Hx + G[v][i].w; gx = dis[to]; que.push({to, hx,gx}); } } while(!que.empty()) que.pop(); return; } int main(){ while(~scanf(" %d %d",&N,&M)){ for(int i = 1 ; i <= N ; i++) G[i].clear(); for(int i = 1 ; i <= M ; i++){ int u, v, w; scanf("%d%d%d",&u,&v,&w); G[u].push_back({v, w}); G2[v].push_back({u, w}); } scanf(" %d %d %d",&start, &End, &K); //此题要求start和End相同的时候 第一短路不是0 ,所以K++ if(start == End) K++; Dijkstra(); Astar(); printf("%d\n",ans); } return 0; } /* 1 1 2 2 5 2 2 1*/