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

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

时间: 2024-10-15 10:54:24

图论-第k短路的相关文章

图论(A*算法,K短路) :POJ 2449 Remmarguts&#39; Date

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h

[K短路] SDOI2010 魔法猪学院

魔法猪学院 题目背景 感谢@kczno1 @X_o_r 提供hack数据 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与元素之间可以互相转换:能量守恒--. 能量守恒--iPig 今天就在进行一个麻烦的测验.iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定的能量.作为 PKU 的顶尖

班级娱乐赛 K短路计数

K短路计数 同学出的题目,有原题的,但找不到了. Description 题目背景(来源):小 L 从<挑战程序设计竞赛>中翻到了一道图论(暴力)好题. 给定一个 n 个定顶点,边长为 1 的有向图邻接矩阵.求这个图中长度为 k 的不同的路径 总数.(不懂看样例) 1.路径中同一条边可经过多次. 2.输出答案对(1e7)+7 取模. 3.图中会有自环. Input 输入文件名为 count.in. 输入第一行为两个用空格隔开正整数,分别为 n 和 k 的值. 接下来输入 n 行(一个普通的邻接

poj2449:第k短路问题

Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, he told them a story. "Prince Remmarguts lives in his kingdom UDF – United Delta of Freedom. One

图的第k短路

[问题描述] 给你一个有向图,求从1到n的第k短路. [解法] SPFA+A*搜索. 1 A*算法 A*算法在人工智能中是一种典型的启发式搜索算法,启发中的估价是用估价函数表示的: h(n)=f(n)+g(n) 其中f(n)是节点n的估价函数,g(n)表示实际状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价.另外定义h'(n)为n到目标节点最佳路径的实际值.如果h'(n)≥h(n)则如果存在从初始状态走到目标状态的最小代价的解,那么用该估价函数搜索的算法就叫A*

POJ 2499 A*求第K短路

DES就是给你一个图.然后给你起点和终点.问你从起点到终点的第K短路. 第一次接触A*算法. // 大概懂思路了.A*算法需要的估价函数里的两个函数.一个是起点到当前点的消耗. //一个是当前点到目标点的估测消耗.所以需要用Dijstra或者Spfa求出目标点到所有点的最短路. //然后就可以用A*算法来求了. // 确实.学了位运算.链式表. #include<cstdio> #include<iostream> #include<queue> #include<

poj2449 Remmarguts&#39; Date,第K短路

点击打开链接 SPFA  + A* #include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; struct node { int v, dis, f, next; friend bool operator <(node a, node b){ return a.f>b.f; } }; const int INF =

poj 2449 Remmarguts&#39; Date k短路

/*poj 2449 k短路 A* 估价函数是 s到i的距离+i到t的距离 */ #include<cstdio> #include<queue> #include<vector> #define inf 1e7 #define maxn 100010 using namespace std; int n,m,S,T,K,num1,num2,head1[maxn],head2[maxn],dis[maxn]; int q[maxn],hea,tai,f[maxn],cn

POJ 2449Remmarguts&#39; Date K短路模板 A*+SPFA

太水了我不想说了,模板在这里 14312K 313MS 1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int v[100010],v2[100010],c[100010],c2[100010],s,t,k,duin; 7 int n,m,point[1010],next[100010],cnt=0,