就是裸的求次短路,可以用k短路試試手
A*算法的估價函數可表示爲:
f’(n) = g’(n) + h’(n)
其中f(n) 是節點n的估價函數,g(n)是在狀態空間中從初始節點到n節點的實際代價,h(n)是從n到目標節點最佳路徑的估計代價。在這裏主要是h(n)體現了搜索的啓發信息,因爲g(n)是已知的。如果說詳細 點,g(n)代表了搜索的廣度的優先趨勢。
這裏,f’(n)是估價函數,g’(n)是起點到終點的最短路徑值,h’(n)是n到目標的最短路經的啓發值。由 於這個f’(n)其實是無法預先知道的,所以我們用前面的估價函數f(n)做近似。g(n)代替g’(n),但 g(n)>=g’(n) 纔可(大多數情況下都是滿足的,可以不用考慮),h(n)代替h’(n),但h(n)<=h’(n)纔可(這一點特別的重 要)。可以證明應用這樣的估價函數是可以找到最短路徑的,也就是可採納的。我們說應用這種估價函數的 最好優先算法就是A*算法。
給代碼
這個題太坑了, 一直以爲是有向圖, 狂WA不止。。。。
程序裏寫了幾個最短路因爲一開始查錯。。。。
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 20010
#define M 800010
#define next Next
#define begin Begin
#define oo 0x3f3f3f
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, s, t) for(int i = s; i <= t; ++i)
#define erep(i, u) for(int i = begin[u]; i; i = next[i])
struct node {
int u, d;
bool operator < (const node &rhs) const {
return d > rhs.d;
}
};
struct srh {
int pos, g, f;
bool operator < (const srh &rhs) const {
return f > rhs.f || (rhs.f == f && rhs.g<g);
}
};
struct dijkstra {
int n, m, dis[N], vis[N];
int begin[N], to[M], next[M], w[M], e;
void init() {
e = 0;
mem(vis, 0);
mem(begin, 0);
rep(i, 0, n) dis[i] = oo;
}
void add(int u, int v, int val) {
to[++e] = v;
next[e] = begin[u];
w[e] = val;
begin[u] = e;
}
/* void ADD(int x, int y) {
to1[e] = y;
next1[e] = begin1[x];
begin1[x] = e;
}*/
priority_queue<node>q;
void dij(int s) {
while(!q.empty()) q.pop();
q.push((node){s, 0});
dis[s] = 0;
while(!q.empty()){
node t = q.top(); q.pop();
int u = t.u, v;
if(vis[u]) continue;
vis[u] = 1;
erep(i, u)
if(dis[v = to[i]] > dis[u]+w[i]) {
dis[v] = dis[u] + w[i];
q.push((node){v, dis[v]});
}
}
}
/* void spfa(int s) {
queue<int> q;
vis[s] = 1;
dis[s] = 0;
q.push(s);
while(!q.empty()) {
int u = q.front(), v;
q.pop();
vis[u] = 0;
erep(i, u)
if(dis[v = to[i]] > dis[u] + w[i]) {
dis[v] = dis[u] + w[i];
if(!vis[v]) q.push(v), vis[v] = 1;
}
}
}*/
priority_queue<srh> Q;
void _A(int s, int t, int cnt = 0) {
while(!Q.empty()) Q.pop();
Q.push((srh){s, 0, dis[s]});
while(!Q.empty()) {
srh A = Q.top(); Q.pop();
int u = A.pos;
if(u == t)
if((++cnt) == 2) {
cout << A.g << endl;
return ;
}
erep(i, u)
Q.push((srh){to[i], A.g+w[i], A.g+w[i]+dis[to[i]]});
}
}
void solve() {
while(~scanf("%d%d", &n, &m)) {
init();
rep(i, 1, m) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
add(y, x, z); add(x, y, z);
}
dij(n);
// spfa(n);
_A(1, n);
}
}
}P;
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("res.out", "w", stdout);
#endif
P.solve();
return 0;
}