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(好吧,其实已经咕咕咕了...) 基础算法 贪心 枚举 分 ...
随机推荐
- php批量 下载图片
<?php set_time_limit(0); $file = fopen("index.csv",'r');$temp = [];$i=0;$firstsku='';wh ...
- vue-cli3安装
1.如果原来安装过vue-cli,需要先卸载,命令:npm uninstall vue-cli -g :这步如果出现问题,可能是npm 的全局路径被更改, 运行如下命令:npm config set ...
- (一)pandas的两种对象
将鱼图像数据进行操作,使用numpy知识 import numpy as np import matplotlib.pyplot as plt %matplotlib inline #咱们可以不用sh ...
- web 部署专题(四):压力测试(二)压力测试实例 flask 四种wsgi方式对比(tornado,Gunicorn,Twisted,Gevent)
使用工具:siege 代码结构: hello.py templates |--hello.html hello.py代码: from flask import Flask, render_templa ...
- .NET Core 微服务—API网关(Ocelot) 教程 [一]
前言: 最近在关注微服务,在 eShop On Containers 项目中存在一个API网关项目,引起想深入了解下它的兴趣. 一.API网关是什么 API网关是微服务架构中的唯一入口,它提供一个单独 ...
- 关于jquery.unobtrusive-ajax.js 回调函数无效 的解决办法
今天新项目的时候写MVC的时候使用到了Ajax.BeginForm,发现它的回调函数怎么都不响应,最后在网上查找了相关资料跟自己写的一些代码测试, 总算找到了原因:jquery.unobtrusive ...
- day1:注释和变量
1.注释的作用:对代码的解释,方便以后阅读代码 2.常用的快捷键:ctrl+q:notepad++的注释ctrl+/:pycharm的注释ctrl+c:复制ctrl+v:粘贴ctrl+z:撤销ctrl ...
- git本地创建分支,并提交到github上去
很多时候,我们再开发的时候需要分支. 那么怎么在本地创建分支,并提交到github或者是远程仓库中呢? 其实很简单: 第一步: git checkout -b dev 创建新的分支 第二步: ...
- day9 python之文件操作
1.文件操作 1.1 基本模式 # 格式 f = open("相对路径/绝对路径",mode = "模式",encoding = "编码级" ...
- 高效C++:构造/析构/赋值
了解C++默认提供和调用的函数 编译器会自动为每一个空类创建构造函数.拷贝构造函数.赋值运算符以及析构函数 不要使用编译器自动创建的函数,要杜绝这种情况发生,自己编写这些函数 如果不想使用编译器自动生 ...