图论-第k短路

Posted ghcred

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论-第k短路相关的知识,希望对你有一定的参考价值。

A* 做法

(f(p)=g(p)+h(p))(f(p)) 作为优先队列比较函数用来比较的值, (g(p)) 是当前路径到 (p) 的距离, (h(p))(p) 点到终点最短路(预处理可以得到)。

每个点出队次数 (k),就说明当前找到的是到这个点的 (k) 短路。

关键代码

void astar(int bg)
{
    int cnt = 0;
    A.push(ast(bg, 0));
    while (!A.empty()) {
        ast p = A.top();
        A.pop();
        if (p.v == N) {
            if (p.w > E)
                break;
            E -= p.w, ++Ans;
        }
        for (int i = G[p.v].size() - 1; i >= 0; --i) {
            edge e = G[p.v][i];
            A.push(ast(e.v, p.w + e.w));
        }
    }
    return;
}

一道裸题: 【SDOI2010】魔法猪学院

#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

typedef double db;

const int _N = 5100;
const db INF = 1e9;

struct edge {
    int v;
    db w;
    
    edge(int v = 0, db w = 0)
        : v(v), w(w) { }
};

struct data {
    int v;
    db w;
    
    data(int v = 0, db w = 0)
        : v(v), w(w) { }
        
    bool operator < (const data &tmp)
    const
    {
        return w > tmp.w;
    }
};

db E, dis[_N];

struct ast {
    int v;
    db w;
    
    ast(int v = 0, db w = 0)
        : v(v), w(w) { }
    
    bool operator < (const ast &tmp)
    const
    {
        return w + dis[v] > tmp.w + dis[tmp.v];
    }
};

priority_queue<data> Q;
priority_queue<ast> A;
vector<edge> G[_N], H[_N];
int Ans, N, M;

void Gins(int a, int b, db c) { G[a].push_back(edge(b ,c)); return; }

void Hins(int a, int b, db c) { H[a].push_back(edge(b, c)); return; }

void dfs(int x, db cost)
{
    if (cost + dis[x] > E) return;
    if (x == N) {
        A.push(cost);
        return;
    }
    for (int i = G[x].size() - 1; i >= 0; --i) {
        edge e = G[x][i];
        dfs(e.v, cost + e.w);
    }
    return;
}

void init(int bg)
{
    for (int i = 1; i <= N; ++i)
        dis[i] = INF;
    Q.push(data(bg, dis[bg] = 0));
    while (!Q.empty()) {
        data p = Q.top();
        Q.pop();
        if (dis[p.v] != p.w) continue;
        for (int i = H[p.v].size() - 1; i >= 0; --i) {
            edge e = H[p.v][i];
            if (dis[e.v] > p.w + e.w)
                dis[e.v] = p.w + e.w, Q.push(data(e.v, dis[e.v]));
        }
    }
    return;
}

void astar(int bg)
{
    int cnt = 0;
    A.push(ast(bg, 0));
    while (!A.empty()) {
        ast p = A.top();
        A.pop();
        if (p.v == N) {
            if (p.w > E)
                break;
            E -= p.w, ++Ans;
        }
        for (int i = G[p.v].size() - 1; i >= 0; --i) {
            edge e = G[p.v][i];
            A.push(ast(e.v, p.w + e.w));
        }
    }
    return;
}

int main()
{
    scanf("%d%d%lf", &N, &M, &E);
    for (int i = 1; i <= M; ++i) {
        int a, b;
        db c;
        scanf("%d%d%lf", &a, &b, &c);
        Gins(a, b, c), Hins(b, a, c);
    }
    init(N);
    astar(1);
    printf("%d
", Ans);
    return 0;
}

以上是关于图论-第k短路的主要内容,如果未能解决你的问题,请参考以下文章

[图论]最短路系列

图论1-k短路

图论----最短路问题

图论 k短路

图论(A*算法,K短路) :POJ 2449 Remmarguts' Date

图论算法