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;
}
原文地址:https://www.cnblogs.com/pbvrvnq/p/8530164.html