A星 求K短路径 POJ 2449

本文介绍了一种结合Dijkstra和A*算法的方法,用于求解带有限次访问约束的最短路径问题。通过示例代码展示了算法的具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 dijkstra+A*。

 

  1#include<stdio.h>
  2#include<queue>
  3#include<memory.h>
  4 usingnamespace std;
  5 #define oo 1000000000
  6#define V 1005
  7#define E 200010
  8int i, j, ans, u, v, l, n, m, s, t, num, k;
  9int dist[V], head[V], nxt[E], ev[E], ew[E], vis[V], head_r[V], nxt_r[E],
10        ev_r[E], ew_r[E];
11struct node
12{
13    int u, l;
14    friend booloperator<(node a, node b)
15    {
16        return a.l > b.l;
17    }
18    node(int a =0, int b =0, int c =0, int d =0) :
19        u(a), l(b)
20    {
21    }
22} x, y;
23priority_queue<node> q;
24void add_edge(int u, int v, int l)
25{
26    nxt[++num] = head[u];
27    head[u] = num;
28    ev[num] = v;
29    ew[num] = l;
30}
31void add_r_edge(int u, int v, int l)
32{
33    nxt_r[++num] = head_r[u];
34    head_r[u] = num;
35    ev_r[num] = v;
36    ew_r[num] = l;
37}
38void dijkstra()
39{
40    int i;
41    q = priority_queue<node> ();
42    memset(vis, 0, sizeof(vis));
43    for (i =1; i <= n; i++)
44        dist[i] = oo;
45    dist[t] =0;
46    q.push(node(t, 0));
47    while (!q.empty())
48    {
49        x = q.top();
50        q.pop();
51        if (vis[x.u] ==0)
52        {
53            for (i = head_r[x.u]; i; i = nxt_r[i])
54            {
55                y.u = ev_r[i];
56                y.l = x.l + ew_r[i];
57                if (y.l < dist[y.u])
58                {
59                    dist[y.u] = y.l;
60                    q.push(y);
61                }
62            }
63        }
64        vis[x.u] =1;
65    }
66}
67int A_star()
68{
69    int i;
70    q = priority_queue<node> ();
71    memset(vis, 0, sizeof(vis));
72    if (dist[s] == oo)
73        return-1;
74    q.push(node(s, dist[s]));
75    while (!q.empty())
76    {
77        x = q.top();
78        q.pop();
79        vis[x.u]++;
80        if (x.u == t && vis[x.u] == k)
81            return x.l;
82        if (vis[x.u] <= k)
83            for (i = head[x.u]; i; i = nxt[i])
84            {
85                y.u = ev[i];
86                y.l = x.l - dist[x.u] + ew[i] + dist[y.u];
87                q.push(y);
88            }
89    }
90    return-1;
91}
92int main()
93{
94    scanf("%d%d", &n, &m);
95    num =0;
96    memset(head, 0, sizeof(head));
97    memset(nxt, 0, sizeof(nxt));
98    for (i =0; i < m; i++)
99    {
100        scanf("%d%d%d", &u, &v, &l);
101        add_edge(u, v, l);
102        add_r_edge(v, u, l);
103    }
104    scanf("%d%d%d", &s, &t, &k);
105    if (s == t)
106        k++;
107    dijkstra();
108    ans = A_star();
109    printf("%d\n", ans);
110    return0;
111}

 

PS:在网上找到两不错说法,也奉上:http://imlazy.ycool.com/post.1956603.html              

                                                          http://richardxx.yo2.cn/articles/a%e7%ae%97%e6%b3%95%e8%a7%a3k-th-shortest-path.html

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值