K短路 学习笔记
K短路,顾名思义,是让你求从$s$到$t$的第$k$短的路。
暴力当然不可取,那么我们有什么算法可以解决这个问题?
--------------------------
首先,我们要维护一个堆。
struct node
{
int dist,pos;
bool operator <(const node&x) const
{
return dist>x.dist;
}
}
priority_queue<node> q;
这个堆是用来干什么的?
----------------------------------------------
这时候要提到一种新算法:A*算法。
估价函数:$f[i]=g[i]+h[i]$。其中,$g[i]$是从起点$s$走,按照这条路径到当前点已经走了多少路程,$h[i]$是当前点到终点$t$的最短路。
我们用之前开设的堆来维护这个估价函数,这样到达第k次终点$t$的路径即为所求。
Code(这里是[SDOI2010]魔法猪学院的A*算法):
void Astar(int kk)
{
priority_queue<SKT> q;
memset(vis,,sizeof(vis));
x.pos=;x.dist=0.0;x.h=0.0;
q.push(x);
while(!q.empty())
{
int now=q.top().pos;double d=q.top().dist;double hh=q.top().h;q.pop();
if (d>E) return;
vis[now]++;
if (now==n){ans++;E-=d;continue;}
if (vis[now]>kk) continue;
for (int i=head[now];i;i=edge[i].next)
{
int to=edge[i].to;
SKT Faker;
Faker.pos=to;Faker.h=hh+edge[i].dis;Faker.dist=Faker.h+dis[to];
q.push(Faker);
}
}
}
----------------------------------
每个点到终点$t$的最短路怎么求?很简单,我们只要在建图的时候再建一个反向图,从终点跑单源最短路径即可。
Code:
void spfa()
{
for (int i=;i<=n;i++) dis[i]=0x3f3f3f3f;
queue<int> q;
q.push(n);dis[n]=0.0;vis[n]=;
while(!q.empty())
{
int now=q.front();q.pop();vis[now]=;
for (int i=Head[now];i;i=Edge[i].next)
{
int to=Edge[i].to;
if (dis[to]>dis[now]+Edge[i].dis)
{
dis[to]=dis[now]+Edge[i].dis;
if (!vis[to]) q.push(to),vis[to]=;
}
}
}
}
----------------------------
近乎于K短路的裸题,只需要注意$u$大于$v$即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=;
const int maxm=;
int dis[maxn],vis[maxn];
int n,m,k;
struct SKT {
int v;
int dist;
bool operator < (const SKT&p) const {
return dist+dis[v]>p.dist+dis[p.v];
}
};
SKT x;
struct Node
{
int next,to,dis;
}edge[maxm],cont[maxm];
int heade[maxm],headc[maxm],cnt;
inline void add(int from,int to,int dis)
{
edge[++cnt].next=heade[from];
edge[cnt].to=to;
edge[cnt].dis=dis;
heade[from]=cnt;
cont[cnt].next=headc[to];
cont[cnt].to=from;
cont[cnt].dis=dis;
headc[to]=cnt;
}
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
void spfa()
{
queue<int> q;
for (int i=;i<=n;i++) dis[i]=0x7fffffff;
q.push();dis[]=;vis[]=;
while(!q.empty())
{
int now=q.front();q.pop();vis[now]=;
for (int i=headc[now];i;i=cont[i].next)
{
int to=cont[i].to;
if (dis[to]>dis[now]+cont[i].dis)
{
dis[to]=dis[now]+cont[i].dis;
if (!vis[to]) q.push(to),vis[to]=;
}
}
}
}
void Astar()
{
int ans=;
priority_queue<SKT> q;
x.v=n;x.dist=;
q.push(x);
while(!q.empty())
{
SKT now=q.top();q.pop();
if (now.v==) printf("%d\n",now.dist),++ans;
if (ans==k) return;
for (int i=heade[now.v];i;i=edge[i].next)
{
int to=edge[i].to;
if (to<now.v)
{
SKT Faker=now;
Faker.v=to;Faker.dist=now.dist+edge[i].dis;
q.push(Faker);
}
}
}
while(ans<k) cout<<-<<endl,++ans;
return;
}
signed main()
{
n=read(),m=read(),k=read();
for (int i=;i<=m;i++)
{
int x=read(),y=read(),z=read();
if (x>y) add(x,y,z);
}
spfa();
Astar();
return ;
}
K短路 学习笔记的更多相关文章
- A* k短路 学习笔记
题目大意 n个点,m条边有向图,给定S,T,求不严格k短路 n<=1000 m<=100000 k<=1000 不用LL 分析 A*算法 f(i)表示从S出发经过i到T的估价函数 \ ...
- 【学习笔记】K 短路问题详解
\(k\) 短路问题简介 所谓"\(k\) 短路"问题,即给定一张 \(n\) 个点,\(m\) 条边的有向图,给定起点 \(s\) 和终点 \(t\),求出所有 \(s\to t ...
- bzoj 1598: [Usaco2008 Mar]牛跑步 [k短路 A*] [学习笔记]
1598: [Usaco2008 Mar]牛跑步 题意:k短路 ~~貌似A*的题目除了x数码就是k短路~~ \[ f(x) = g(x) + h(x) \] \(g(x)\)为到达当前状态实际代价,\ ...
- [原创]java WEB学习笔记71:Struts2 学习之路-- struts2常见的内建验证程序及注意点,短路验证,非字段验证,错误消息的重用
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 算法笔记--次小生成树 && 次短路 && k 短路
1.次小生成树 非严格次小生成树:边权和小于等于最小生成树的边权和 严格次小生成树: 边权和小于最小生成树的边权和 算法:先建好最小生成树,然后对于每条不在最小生成树上的边(u,v,w)如果我们 ...
- 学习笔记之Java程序设计实用教程
Java程序设计实用教程 by 朱战立 & 沈伟 学习笔记之JAVA多线程(http://www.cnblogs.com/pegasus923/p/3995855.html) 国庆休假前学习了 ...
- kruskal重构树学习笔记
\(kruskal\) 重构树学习笔记 前言 \(8102IONCC\) 中考到了,本蒟蒻不会,所以学一下. 前置知识 \(kruskal\) 求最小(大)生成树,树上求 \(lca\). 算法详 ...
- Day 4 学习笔记 各种图论
Day 4 学习笔记 各种图论 图是什么???? 不是我上传的图床上的那些垃圾解释... 一.图: 1.定义 由顶点和边组成的集合叫做图. 2.分类: 边如果是有向边,就是有向图:否则,就是无向图. ...
- OI知识点|NOIP考点|省选考点|教程与学习笔记合集
点亮技能树行动-- 本篇blog按照分类将网上写的OI知识点归纳了一下,然后会附上蒟蒻我的学习笔记或者是我认为写的不错的专题博客qwqwqwq(好吧,其实已经咕咕咕了...) 基础算法 贪心 枚举 分 ...
随机推荐
- 用python实现栈/队列/双端队列/链表
栈是元素的有序集合,添加操作与移除操作都发生在其顶端,先进后出栈操作:创建空栈,增删(顶端),查(顶端元素,元素个数,是否为空)应用:将十进制数转换成任意进制数 class Stack: # 用列表创 ...
- redux中的reducer为什么必须(最好)是纯函数
为什么reducer最好是纯函数? 首先你得看看文档怎么说reducer的作用的,‘接收旧的 state 和 action,返回新的 state’,他起的是一个对数据做简单处理后返回state的作用. ...
- 大前端时代搞定PC/Mac端开发,我有绝招
如果你是一位前端开发工程师,对"跨平台"一词应该不会感到陌生.像常见的前端框架:比如React.Vue.Angular,它们可以做网页端,也可以做移动端,但很少能做到跨PC.Mac ...
- 数据可视化之powerBI基础(十一)Power BI中的数据如何导出到Excel中?
https://zhuanlan.zhihu.com/p/64415543 把Excel中数据加载到PowerBI中我们都已经熟悉了,但是怎么把在PowerBI中处理好的数据导出到Excel中呢?毕竟 ...
- jquery 选项卡切换、选项卡封装、简单的jquery选项卡封装、tab切换效果
相信选项卡切换是大家常用的效果单独写一个选项卡切换很方便但是要是一个页面出现多个选项卡不做封装的话会显得代码很杂乱 <div class="bodyCenter"> & ...
- Go的100天之旅-常量
常量 简介 道可道,非常道.这里常道指的永恒不变的道理,常有不变的意思.顾名思义和变量相比,常量在声明之后就不可改变,它的值是在编译期间就确定的. 下面简单的声明一个常量: const p int = ...
- 阿里面试官:这些软件测试面试题都答对了,I want you!
[ 你悄悄来,请记得带走一丝云彩 ] 测试岗必知必会 01请描述如何划分缺陷与错误严重性和优先级别? 给软件缺陷与错误划分严重性和优先级的通用原则: 1. 表示软件缺陷所造成的危害和恶劣程度. 2. ...
- Ethical Hacking - GAINING ACCESS(22)
CLIENT SIDE ATTACKS - BeEf Framework Browser Exploitation Framework allowing us to launch a number o ...
- Python Ethical Hacking - TROJANS Analysis(5)
Spoofing File Extention - A trick. Use the Kali Linux Program - Characters 1. Open the program. 2. F ...
- 机房vscode使用方法
问题 众所周知,机房中的电脑有一个win7系统,(非常的好,摆脱linux了),同时win7上有一个 vscode ,更好了. 但是!vscode 由于老师不允许联网,导致插件无法安装,更为恶心的事, ...