POJ 3255 A* k_th path
就是裸的求次短路,可以用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;
}