第k短路 演算法詳解(圖解)與模板(A* 演算法)
阿新 • • 發佈:2018-12-15
老規矩,先放模板,有時間放圖解
#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;
}