1. 程式人生 > >第k短路 演算法詳解(圖解)與模板(A* 演算法)

第k短路 演算法詳解(圖解)與模板(A* 演算法)

老規矩,先放模板,有時間放圖解

#include <map>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <algorithm>
#define lowbit(a) (a&(-a))
#define _mid(a,b) ((a+b)/2) #define _mem(a,b) memset(a,0,(b+3)<<2) #define fori(a) for(int i=0;i<a;i++) #define forj(a) for(int j=0;j<a;j++) #define ifor(a) for(int i=1;i<=a;i++) #define jfor(a) for(int j=1;j<=a;j++) #define mem(a,b) memset(a,b,sizeof(a)) #define IO do{\ ios::sync_with_stdio(false);\ cin.tie(0);\ cout.tie(0);}while(0)
#define mp(a,b) make_pair(a,b) #define pb(a) push_back(a) #define debug(a) cout <<(a) << endl using namespace std; typedef long long ll; const int maxn = 1e3+5; const int INF = 0x3f3f3f3f; int s,t,k; bool vis[maxn]; int dis[maxn]; struct node{ int v,c; node(int _v=0,int _c=0) :
v(_v),c(_c) {}; //構造 node(){}; bool operator < (const node & buf) const{ return c+ dis[v] > buf.c + dis[buf.v]; } }; struct edge{ int v,cost; edge(int _v=0,int _c=0) : v(_v),cost(_c){}; }; vector <edge> e[maxn],reve[maxn]; //反向存圖 priority_queue<node> q; void dijkstra(int n,int s){ //dijkstra+佇列優化 mem(vis,false); mem(dis,0x3f); while(!q.empty()) q.pop(); dis[s] = 0; q.push(node(s,0)); while(!q.empty()){ node tmp = q.top(); q.pop(); int u = tmp.v; if(vis[u]) continue; vis[u] = true; fori(e[u].size()){ int v = e[u][i].v; int cost = e[u][i].cost; if(!vis[v] && dis[v] > dis[u] + cost){ dis[v] = dis[u] + cost; q.push(node(v,dis[v])); } } } } int aStar(int s){ while(!q.empty()) q.pop(); q.push(node(s,0)); k--; while(!q.empty()){ node pre = q.top(); q.pop(); int u = pre.v; if(u == t){ if(k) k--; else return pre.c; } fori(reve[u].size()){ int v = reve[u][i].v; int c = reve[u][i].cost; q.push(node(v,pre.c+c)); } } return -1; } void addedge(int u,int v,int w){ reve[u].pb(edge(v,w)); e[v].pb(edge(u,w)); } int main() { IO; int n,m,u,v,w; while(cin>>n >> m){ fori(n+2){ e[i].clear(); reve[i].clear(); } fori(m){ cin >> u >> v >> w; addedge(u,v,w); } cin >> s >> t >> k; dijkstra(n,t); if(dis[s] == INF) cout << -1 << endl; else{ if(s == t) k ++; ///如果起點==終點不能算上dis = 0 的這一點 cout << aStar(s) << endl;; } } return 0; }