码迷,mamicode.com
首页 > 其他好文 > 详细

图论-第k短路

时间:2018-10-11 22:38:57      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:clu   lin   ini   \n   ack   queue   队列   oid   break   

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\n", Ans);
    return 0;
}

图论-第k短路

标签:clu   lin   ini   \n   ack   queue   队列   oid   break   

原文地址:https://www.cnblogs.com/ghcred/p/9775373.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!