• A* 算法求第 K 短路


    一种具有 (f(n)=g(n)+h(n)) 策略的启发式算法能成为 A* 算法的充分条件是:

    • 搜索树上存在着从起始点到终了点的最优路径。
    • 问题域是有限的。
    • 所有结点的子结点的搜索代价值 (>0)
    • (h(n) le h^ast (n))(h^ast (n)) 为实际问题的代价值)。

    Remmarguts' Date

    求 S 到 T 的第 K 短路。

    思路:

    (1) 将有向图的所有边反向,以原终点T为源点,求解T到所有点的最短距离。

    (2) 新建一个优先队列,将源点S加入到队列中。

    (3) 从优先级队列中弹出f(p)最小的点p,如果点p就是T,则计算T出队的次数。如果当前为T的第K次出队,则当前路径的长度就是S到T的第K短路的长度,算法结束;否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先队列。

    Z_Mendez

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    int n, m, S, T, K, ans=-1;
    int head[1005], nex[100005], to[100005], w[100005];
    int rhead[1005], rnex[100005], rto[100005], rw[100005];
    int h[1005]; bool v[1005];
    struct node {
    	int t, d;
    	bool operator < (const node& A) const {return d>A.d; }
    }; 
    priority_queue<node> q;
    struct star {
    	int t, g, f;
    	bool operator < (const star& A) const {return f>A.f || f==A.f && g>A.g; }
    };
    priority_queue<star> Q;
    
    inline void add(int x, int y, int z) {
    	nex[++head[0]]=head[x], head[x]=head[0], to[head[0]]=y, w[head[0]]=z;
    }
    inline void radd(int x, int y, int z) {
    	rnex[++rhead[0]]=rhead[x], rhead[x]=rhead[0], rto[rhead[0]]=y, rw[rhead[0]]=z;
    }
    
    inline void astar() {
    	if (S==T) ++K;
    	if (h[S]==0x3f3f3f3f) return;
    	Q.push((star) {S, 0, h[S]});
    	register int cnt=0;
    	
    	while (!Q.empty()) {
    		register star now=Q.top(); Q.pop();
    		if (now.t==T) if (++cnt>=K) {ans=now.g; return; }
    		for (int i=head[now.t]; i; i=nex[i])
    			Q.push((star) {to[i], now.g+w[i], now.g+w[i]+h[to[i]]});
    	}
    }
    
    int main() {
    	while (~scanf("%d%d", &n, &m)) {
    		memset(head, 0, sizeof head), memset(rhead, 0, sizeof rhead);
    		for (int i=1, A, B, C; i<=m; ++i) scanf("%d%d%d", &A, &B, &C),
    			add(A, B, C), radd(B, A, C);
    		scanf("%d%d%d", &S, &T, &K);
    		
    		memset(h, 0x3f, sizeof h);
    		q.push((node) {T, h[T]=0});
    		while (!q.empty()) {
    			register node now=q.top(); q.pop();
    			if (v[now.t]) continue; v[now.t]=true;
    			for (int i=rhead[now.t]; i; i=rnex[i])
    				if (now.d+rw[i] < h[rto[i]])
    					h[rto[i]] = now.d + rw[i], q.push((node) {rto[i], h[rto[i]]});
    		}
    		
    		astar();
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    mmap和MappedByteBuffer
    Linux命令之TOP
    Linux命令之ss
    MySql Cluster
    HttpClient配置
    注释驱动的 Spring cache 缓存介绍
    Spring AOP 实现原理与 CGLIB 应用
    AspectJ本质剖析
    B树
    imagick-3.1.0RC2 安装错误
  • 原文地址:https://www.cnblogs.com/greyqz/p/11856198.html
Copyright © 2020-2023  润新知