题面

经典的 \(\text{A*}\) 算法例题。

我们可以把估价函数 \(f(i)\) 设置成当前点 \(i\) 到终点 \(t\) 的最短距离,这可以建反图使用 \(\text{Dijkstra}\) 算法预处理出。

然后一遍 \(\text{BFS}\) 即可。

注意当起点与终点相同时要 \(++k\) 。

#include <bits/stdc++.h>
#define DEBUG fprintf(stderr, "Passing [%s] line %d\n", __FUNCTION__, __LINE__)
#define itn int
#define gI gi using namespace std; typedef pair <int, int> PII;
typedef pair <int, PII> PIII; inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
} const int maxn = 1003, maxm = 100003; int s, t, k, n, m;
int tot, head[maxn], ver[maxm * 2], nxt[maxm * 2], edge[maxm * 2], headu[maxn];
int dist[maxn], f[maxn], g[maxn], vis[maxn]; inline void add(int *h, int u, int v, int w)
{
ver[++tot] = v, edge[tot] = w, nxt[tot] = h[u], h[u] = tot;
} inline void Dijkstra() //预处理估价函数值
{
priority_queue <PII, vector <PII>, greater <PII> > q;
memset(dist, 0x3f, sizeof(dist));
dist[t] = 0;
q.push(make_pair(0, t));
while (!q.empty())
{
int u = q.top().second; q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = headu[u]; i; i = nxt[i])
{
int v = ver[i], w = edge[i];
if (dist[v] > dist[u] + w)
{
dist[v] = dist[u] + w;
q.push(make_pair(dist[v], v));
}
}
}
memcpy(f, dist, sizeof(f));
} inline int A_star()
{
priority_queue <PIII, vector <PIII>, greater <PIII> > q;
//优先队列中存储 3 个信息:估价函数值、实际距离与当前节点编号
memset(vis, 0, sizeof(vis));
q.push(make_pair(f[s], make_pair(0, s))); //加入起点
while (!q.empty())
{
int now = q.top().second.second, dis = q.top().second.first;
q.pop();
if (vis[now] >= k) continue; //已经搜过了 K 短路
++vis[now];
if (now == t && vis[now] == k) return dis; //找到了结果
for (int i = head[now]; i; i = nxt[i])
{
int v = ver[i], w = edge[i];
if (vis[v] < k)
{
q.push(make_pair(f[v] + dis + w, make_pair(dis + w, v))); //进行扩展
}
}
}
return -1;
} int main()
{
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
n = gi(), m = gi();
for (int i = 1; i <= m; i+=1)
{
int u = gi(), v = gi(), w = gi();
add(head, u, v, w), add(headu, v, u, w); //建反图
}
s = gi(), t = gi(), k = gi();
if (s == t) ++k;
Dijkstra();
printf("%d\n", A_star());
return 0;
}

题解【AcWing178】第K短路的更多相关文章

  1. 【USACO Mar08】 奶牛跑步 A-star k短路

    Description Bessie准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚. Bessie也不想跑得太远,所以她想走最短的路经. 农场上一共有M( ...

  2. BZOJ1975 [Sdoi2010]魔法猪学院 k短路

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1975 题意概括 给出一个无向图,让你走不同的路径,从1到n,路径长度之和不超过E,求最大路径条数. ...

  3. ACM-ICPC 2018 沈阳赛区网络预赛 Made In Heaven(K短路)题解

    思路:K短路裸题 代码: #include<queue> #include<cstring> #include<set> #include<map> # ...

  4. POJ 2449 Remmarguts' Date(第K短路 + A* + 最短路)题解

    题意:找出第k短路,输出长度,没有输出-1 思路:这题可以用A*做.A*的原理是这样,我们用一个函数:f = g + h 来表示当前点的预期步数,f代表当前点的预期步数,g代表从起点走到当前的步数,h ...

  5. poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)

    http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

  6. Bzoj 1975: [Sdoi2010]魔法猪学院 dijkstra,堆,A*,K短路

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1357  Solved: 446[Submit][Statu ...

  7. Bzoj 1598: [Usaco2008 Mar]牛跑步 dijkstra,堆,K短路,A*

    1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 427  Solved: 246[Submit][St ...

  8. BZOJ1073 [SCOI2007]kshort K短路,A*

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1073 题意概括 以距离为第一关键字,字典序为第二关键字,在所有的从S到T的路径中,选择不重复经过某 ...

  9. POJ 2449 - Remmarguts' Date - [第k短路模板题][优先队列BFS]

    题目链接:http://poj.org/problem?id=2449 Time Limit: 4000MS Memory Limit: 65536K Description "Good m ...

随机推荐

  1. 在阿里云服务器上安装mysql及重置密码

    参考链接:https://www.cnblogs.com/ljysy/p/10324854.html 下载与安装MySQL: 这里采用Yum管理好了各种rpm包的依赖,能够从指定的服务器自动下载RPM ...

  2. NetCore文件上传校验返回未授权401,文件仍然执行上传操作,要如何解决呢

    这是代码:https://files.cnblogs.com/files/suterfo/NetCoreTestPro.rar 运行步骤: 一.使用Visual Studio2017打开项目,并F5运 ...

  3. logback日志的基本使用

    logback的日志使用,有两种方式,可以在application.yml文件中配置,不过最常见的还是用一个单独的xml配置文件进行配置: 一.application.yml配置方式 logging: ...

  4. linux 网络接口,ip地址,路由设定

    本文是基于centos 配置DNS条目: 配置文件:/etc/resolv.conf 修改主机名称: 命令:hostname NAME.重启后失效 配置文件:/etc/sysconfig/networ ...

  5. 小白的java学习之路 “ 数组”

    数组 一.什么是数组: 数组是一个变量,存储相同数据类型的一组数据 声明一个变量就是在内存空间划出一块合适的空间 声明一个数组就是在内存空间划出一串连续的空间 二.数组基本要素: 标识符:数组的名称, ...

  6. 微信小程序-骰子游戏2

    这是截图,类似与eclipse 的web 开发. 主界面可以自己编写程序. 可以压大压小等等,过年回家聚会的时候可以试试....

  7. mac 非安全模式 开启

    https://github.com/callmelaoda/communicate/issues/8 open -a Google\ Chrome --args --disable-web-secu ...

  8. git Auto packing the repository in background for optimum performance

    遇到问题: git本地仓库,如果长时间不进行清理,几个月以后的某一天,可能拉取代码的时候突然提示你 git Auto packing the repository in background for ...

  9. vue自学入门-7(vue style scope)

    vue自学入门-1(Windows下搭建vue环境) vue自学入门-2(vue创建项目) vue自学入门-3(vue第一个例子) vue自学入门-4(vue slot) vue自学入门-5(vuex ...

  10. Docker学习笔记(2):使用Dockerfile构建镜像

    Dockerfile是用来构建Docker镜像的文件,是由一系列命令和参数构成的脚本.每条指令都必须为大写字母且后面要跟随至少一个参数,每条指令都会创建一个新的镜像层,并对镜像进行提交. Docker ...