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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章