AcWing 178. 第K短路
题意
给定一张 \(N\) 个点(编号 \(1,2…N\)),\(M\) 条边的有向图,求从起点 \(S\) 到终点 \(T\) 的第 \(K\) 短路的长度,路径允许重复经过点或边。
注意: 每条最短路中至少要包含一条边。
由于直接\(BFS\)搜索空间特别大,所以考虑\(A*\)算法
以从\(x\)点到终点的最短距离为估价函数,那么这个可以通过反向求终点到\(x\)的单源最短距离实现。
当终点\(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短路的更多相关文章
- AcWing:178. 第K短路(A*)
给定一张N个点(编号1,2…N),M条边的有向图,求从起点S到终点T的第K短路的长度,路径允许重复经过点或边. 注意: 每条最短路中至少要包含一条边. 输入格式 第一行包含两个整数N和M. 接下来M行 ...
- POJ 2449 Remmarguts' Date --K短路
题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...
- POJ 2449Remmarguts' Date K短路模板 SPFA+A*
K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...
- BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...
- 【POJ】2449 Remmarguts' Date(k短路)
http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k ...
- poj 2449 Remmarguts' Date K短路+A*
题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...
- 第k短路
poj 2449 模板题 A*+spfa #include<iostream> #include<cstdio> #include<cstring> #inclu ...
- poj 2449(A*求第K短路)
题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...
- K短路
K短路 用dijsktra+A*启发式搜索当点v第K次出堆的时候,这时候求得的路径是k短路.A*算法有一个启发式函数f(p)=g(p)+h(p), 即评估函数=当前值+当前位置到终点的最短距离g(p) ...
- poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)
http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Subm ...
随机推荐
- 2021-3-9 保存csv格式文件
public void SaveCSV(DataTable dt, string fullPath) { FileInfo fi = new FileInfo(fullPath); if (!fi.D ...
- 【游记】NOIP2022 预备赛游记
Day -2 \(NOIP\) 就要来了,\(CSYZ\) 斥巨资给我们在 \(NOIP\) 正式考点举办了一场 \(NOIP\) 预备赛,真是太感动了~~ \(cy\) 说明天要颁奖,激动激动! D ...
- 跟进 .NET 8 Blazor 之 ReuseTabs 支持 Query 属性绑定
ASP.NET 团队和社区在 .NET 8 继续全力投入 Blazor,为它带来了非常多的新特性,特别是在服务端渲染(SSR)方面,一定程度解决之前 WASM 加载慢,Server 性能不理想等局限性 ...
- C#中多线程的用法
1.在C#中使用多线程可以使用Thread 代码例子: public class ThreadExample { public static void ThreadProc() { for (int ...
- 如何利用AI智能聊天机器人10秒钟做出一个故事绘本的神奇插件
原文链接:如何利用AI智能聊天机器人10秒钟做出一个故事绘本的神奇插件 ChatGPT以下称为AI智能聊天机器人 一.AI智能聊天机器人4中集成"Stories"插件 对于已经熟悉 ...
- selenium-wire兼容selenium和requests
背景 在工作中UI自动化中可能会需要用到API来做一些数据准备或清理的事情,那UI操作是略低效的,但API操作相对高效. 而实战课就有这样一个案例,不过那个案例是UI操作和API分开的. 极少会遇到这 ...
- Navicat连接docker mysql出错
一.启动容器 首先启动docker mysql: docker run -itd --name mysql -p 13306:3306 -e MYSQL_ROOT_PASSWORD=123456 my ...
- linux shell根据关键字用sed注释掉整行
一.将带有ab的行注释掉 # cat test # sed -i '/ab/s/^\(.*\)$/#\1/g' test ab是关键字 s是语法替换 ^是行首 $是行尾 \是转义符 数字1带表前述匹配 ...
- No manual entry for ls终极解决办法
No manual entry for ls解决办法,最后一种方法一定能解决你的问题 步骤一:确认man是否已经安装 #which man /usr/bin/man---返回此行,证明已经安装 步骤二 ...
- .NET周刊【9月第2期 2023-09-10】
国内文章 使用 OpenTelemetry 构建 .NET 应用可观测性(2):OpenTelemetry 项目简介 https://www.cnblogs.com/eventhorizon/p/17 ...