题意

给定一张 \(N\) 个点(编号 \(1,2…N\)),\(M\) 条边的有向图,求从起点 \(S\) 到终点 \(T\) 的第 \(K\) 短路的长度,路径允许重复经过点或边。

注意: 每条最短路中至少要包含一条边。

由于直接\(BFS\)搜索空间特别大,所以考虑\(A*\)算法

  1. 以从\(x\)点到终点的最短距离为估价函数,那么这个可以通过反向求终点到\(x\)的单源最短距离实现。

  2. 当终点\(T\), 第\(K\)次被拓展的时候,就得到了\(S\)到\(T\)的第\(K\)短路。

// Problem: 第K短路
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/180/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org) #include <bits/stdc++.h> using namespace std; typedef pair<int, int> PII;
typedef pair<int, pair<int, int>> PIII; const int N = 1010, M = 200010;
int h[N], rh[N], e[M], ne[M], w[M], idx;
int S, T, K, n, m;
int dist[N];
bool st[N];
int cnt[N]; void add(int h[], int a, int b, int c) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
} void Dijkstra() {
priority_queue<PII, vector<PII>, greater<PII>> heap;
memset(dist, 0x3f, sizeof dist);
dist[T] = 0;
heap.push({0, T}); while (heap.size()) {
auto t = heap.top();
heap.pop(); int ver = t.second; if (st[ver]) continue;
st[ver] = true; for (int i = rh[ver]; i != -1; i = ne[i]) {
int j = e[i];
if (dist[j] > dist[ver] + w[i]) {
dist[j] = dist[ver] + w[i];
heap.push({dist[j], j});
}
}
}
} int astar() {
priority_queue<PIII, vector<PIII>, greater<PIII>> heap;
heap.push({dist[S], {0, S}}); while (heap.size()) {
auto t = heap.top();
heap.pop(); int ver = t.second.second, distance = t.second.first;
cnt[ver]++;
if (cnt[T] == K) return distance; for (int i = h[ver]; i != -1; i = ne[i]) {
int j = e[i];
if (cnt[j] < K) {
heap.push({distance + w[i] + dist[j], {distance + w[i], j}});
}
}
} return -1;
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cin >> n >> m;
memset(h, -1, sizeof h);
memset(rh, -1, sizeof rh);
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c;
add(h, a, b, c), add(rh, b, a, c);
}
cin >> S >> T >> K;
if (S == T) K++; //因为最少要经过一条边,当S, T一个点输出0,所以我们先K++ Dijkstra(); cout << astar() << endl; return 0;
}

AcWing 178. 第K短路的更多相关文章

  1. AcWing:178. 第K短路(A*)

    给定一张N个点(编号1,2…N),M条边的有向图,求从起点S到终点T的第K短路的长度,路径允许重复经过点或边. 注意: 每条最短路中至少要包含一条边. 输入格式 第一行包含两个整数N和M. 接下来M行 ...

  2. POJ 2449 Remmarguts' Date --K短路

    题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...

  3. POJ 2449Remmarguts' Date K短路模板 SPFA+A*

    K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...

  4. BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...

  5. 【POJ】2449 Remmarguts' Date(k短路)

    http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k ...

  6. poj 2449 Remmarguts' Date K短路+A*

    题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...

  7. 第k短路

    poj 2449 模板题  A*+spfa #include<iostream> #include<cstdio> #include<cstring> #inclu ...

  8. poj 2449(A*求第K短路)

    题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...

  9. K短路

    K短路 用dijsktra+A*启发式搜索当点v第K次出堆的时候,这时候求得的路径是k短路.A*算法有一个启发式函数f(p)=g(p)+h(p), 即评估函数=当前值+当前位置到终点的最短距离g(p) ...

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

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

随机推荐

  1. IDA函数特征识别自动签名

    IDA函数特征识别自动签名 Vc6编译的有些无法识别一些库里面的函数 测试代码 #include <stdio.h> int main() { printf("123456\n& ...

  2. 知识图谱(Knowledge Graph)- Neo4j 5.10.0 使用 - CQL - 太极拳传承谱系表

    删除数据库中以往的图 MATCH (n) DETACH DELETE n 创建节点 CREATE命令语法 Neo4j CQL"CREATE"命令用于创建没有属性的节点. 它只是创建 ...

  3. 《Kali渗透基础》10. 提权、后渗透

    @ 目录 1:提权 2:Admin 提权为 System 2.1:at 2.2:sc 2.3:SysInternal Suite 2.4:进程注入提权 3:抓包嗅探 4:键盘记录 5:本地缓存密码 5 ...

  4. 如何调用api接口获取到商品数据

    要调用API接口获取商品数据,需要进行以下步骤: 确定API接口 首先需要确定要使用的API接口,可以通过搜索引擎或者相关文档来查找适合的API接口.以淘宝开放平台为例,可以使用淘宝的商品信息查询AP ...

  5. RabbitMQ 如何实现延迟队列?

    延迟队列是指当消息被发送以后,并不是立即执行,而是等待特定的时间后,消费者才会执行该消息. 延迟队列的使用场景有以下几种: 未按时支付的订单,30 分钟过期之后取消订单. 给活跃度比较低的用户间隔 N ...

  6. 深入浅出:SPI机制在JDK与Spring Boot中的应用

    本文分享自华为云社区<Spring高手之路14--深入浅出:SPI机制在JDK与Spring Boot中的应用>,作者:砖业洋__ . Spring Boot不仅是简化Spring应用开发 ...

  7. 每日一库:Prometheus

    什么是 Prometheus Prometheus 是一个开源的系统监控和警报工具,最初由 SoundCloud 开发,并于 2012 年发布为开源项目.它是一个非常强大和灵活的工具,用于监控应用程序 ...

  8. 「joisc2016 - D3T2」回転寿司

    题意大概是这样,「每次操作选出区间中的一个 LIS(strictly),满足其开端是极靠近左端点且大于 \(A\) 的位置,答案即这个 LIS 的末尾,做一个轮换后弹出序列末端」. 首先做几个观察. ...

  9. Springboot简单功能示例-3 实现基本登录验证

    springboot-sample 介绍 springboot简单示例 跳转到发行版 查看发行版说明 软件架构(当前发行版使用) springboot hutool-all 非常好的常用java工具库 ...

  10. 利用SpringBoot项目做一个Mock挡板;基于事件发布动态自定义URL和响应报文

    导入SpringbootWEb依赖 <!--web项目驱动--> <dependency> <groupId>org.springframework.boot< ...