[学习笔记]k短路
A*:我已经忘了怎么写了,反正n=30,m=1000都能卡掉。。。
正解:可持久化左偏树+堆维护可能集合
原论文:http://www.docin.com/p-1387370338.html
概括:
结论:
1.t为根求最短路树T,定义P'为路径s-t的路径P和T没有交集的部分,P’和P都是有序边集
对于P'中相邻边一定存在tail和head的祖先后代关系(或者重合)
2.新定义边的代价:dis[v]+w-dis[u],即换边走的额外可能花费
这样一个P就是:dis[1~n]+∑e∈P' newweight[e]
3.P和P'一一对应。
求法:
1.T为根求最短路树
2.非树边放进u的左偏树内,
3.dfs可持久化合并堆,得到到根路径上的出边的堆
4.堆维护四元组(u,v,pos,val)边集倒数第二条边tail是u,倒数第一条边tail是v,v的这个边的左偏树节点编号pos,P’的代价val
更新:
A.v找到rt[v]最小的加入P的末尾
B.u找到rt[u]下一个最小的边作为新的v和pos,这个边一定是pos的左儿子或者右儿子
初始:(0,1,*,0)要特判
注意特判:
A.rt[v]=0?
B.pos没有左右儿子?
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Miracle{
const int N=;
const int M=+;
int n,m;
double E;
struct node{
int nxt,to;
double val;
}e[M];
int hd[N],cnt=;
void add(int x,int y,double z){
e[++cnt].nxt=hd[x];
e[cnt].to=y;e[cnt].val=z;
hd[x]=cnt;
} struct edge{
int x,y;
double z;
}b[M];
double dis[N];
struct po{
int x;double val;
po(){}
po(int xx,double vv){
x=xx;val=vv;
}
bool friend operator <(po a,po b){
return a.val>b.val;
}
};
priority_queue<po>q;
bool vis[N];
int pre[N];
void dij(){
memset(dis,,sizeof dis);
dis[n]=;
q.push(po(n,));
while(!q.empty()){
po now=q.top();q.pop();
if(vis[now.x]) continue;
int x=now.x;
vis[x]=;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(dis[y]>dis[x]+e[i].val){
dis[y]=dis[x]+e[i].val;
pre[y]=i;
q.push(po(y,dis[y]));
}
}
}
}
bool on[M];
struct tr{
int ls,rs;
int d,id;
double val;
tr(){}
tr(double v,int ddd){
ls=,rs=;val=v;d=;id=ddd;
}
}t[M*];
int tot;
int rt[N];
int merge(int x,int y,int typ){
if(!x||!y) return x+y;
if(t[x].val>t[y].val) swap(x,y);
if(typ){
int nw=++tot;
t[nw]=t[x];
x=nw;
}
t[x].rs=merge(t[x].rs,y,typ);
if(t[t[x].ls].d<t[t[x].rs].d) swap(t[x].ls,t[x].rs);
t[x].d=t[t[x].rs].d+;
return x;
}
struct sol{
int u,v,pos;
double val;
sol(){}
sol(int uu,int vv,int pp,double vd){
u=uu;v=vv;pos=pp;val=vd;
}
bool friend operator <(sol a,sol b){
return a.val>b.val;
}
};
void dfs(int x){
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
rt[y]=merge(rt[y],rt[x],);
dfs(y);
}
}
priority_queue<sol>hp; int main(){
rd(n);rd(m);scanf("%lf",&E);
for(reg i=;i<=m;++i){
rd(b[i].x);rd(b[i].y);scanf("%lf",&b[i].z);
add(b[i].y,b[i].x,b[i].z);
}
dij();
// for(reg i=1;i<=n;++i){
// cout<<i<<" : "<<dis[i]<<endl;
// }
memset(hd,,sizeof hd);
cnt=;
for(reg i=;i<n;++i){
on[pre[i]]=;
int id=pre[i];
add(b[id].y,b[id].x,b[id].z);
}
for(reg i=;i<=m;++i){
if(!on[i]){
t[++tot]=tr(dis[b[i].y]+b[i].z-dis[b[i].x],i);
rt[b[i].x]=merge(rt[b[i].x],tot,);
}
}
dfs(n);
hp.push(sol(,,-,));
double st=dis[];
ll ans=;
while(!hp.empty()){
sol now=hp.top();hp.pop();
E-=now.val+st;
if(E<) break;
++ans;
int u=now.u,v=now.v;
if(now.v==&&now.u==){
if(rt[]){
sol lp=now;
lp.u=;
lp.pos=rt[];
lp.val=t[rt[]].val;
lp.v=b[t[rt[]].id].y;
hp.push(lp);
}
}else{
if(rt[now.v]){
sol lp=now;
lp.u=v;
lp.pos=rt[lp.u];
lp.val+=t[rt[lp.u]].val;
lp.v=b[t[rt[lp.u]].id].y;
hp.push(lp);
}
if(t[now.pos].ls){
sol lp=now;
lp.pos=t[lp.pos].ls;
lp.val+=t[lp.pos].val-t[now.pos].val;
lp.v=b[t[lp.pos].id].y;
hp.push(lp);
}
if(t[now.pos].rs){
sol lp=now;
lp.pos=t[lp.pos].rs;
lp.val+=t[lp.pos].val-t[now.pos].val;
lp.v=b[t[lp.pos].id].y;
hp.push(lp);
}
}
}
ot(ans);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/
[学习笔记]k短路的更多相关文章
- 学习笔记——k近邻法
对新的输入实例,在训练数据集中找到与该实例最邻近的\(k\)个实例,这\(k\)个实例的多数属于某个类,就把该输入实例分给这个类. \(k\) 近邻法(\(k\)-nearest neighbor, ...
- R语言学习笔记—K近邻算法
K近邻算法(KNN)是指一个样本如果在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.即每个样本都可以用它最接近的k个邻居来代表.KNN算法适 ...
- 【学习笔记】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)\)为到达当前状态实际代价,\ ...
- A* k短路 学习笔记
题目大意 n个点,m条边有向图,给定S,T,求不严格k短路 n<=1000 m<=100000 k<=1000 不用LL 分析 A*算法 f(i)表示从S出发经过i到T的估价函数 \ ...
- K短路 学习笔记
K短路,顾名思义,是让你求从$s$到$t$的第$k$短的路. 暴力当然不可取,那么我们有什么算法可以解决这个问题? -------------------------- 首先,我们要维护一个堆. st ...
- [原创]java WEB学习笔记71:Struts2 学习之路-- struts2常见的内建验证程序及注意点,短路验证,非字段验证,错误消息的重用
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 算法笔记--次小生成树 && 次短路 && k 短路
1.次小生成树 非严格次小生成树:边权和小于等于最小生成树的边权和 严格次小生成树: 边权和小于最小生成树的边权和 算法:先建好最小生成树,然后对于每条不在最小生成树上的边(u,v,w)如果我们 ...
- 学习笔记之Java程序设计实用教程
Java程序设计实用教程 by 朱战立 & 沈伟 学习笔记之JAVA多线程(http://www.cnblogs.com/pegasus923/p/3995855.html) 国庆休假前学习了 ...
随机推荐
- php实现图片以base64显示的方法达到效果
目前Data URI scheme支持的类型有: data:text/plain,文本数据data:text/html,HTML代码data:text/html;base64,base64编码的HTM ...
- LintCode_111 爬楼梯
题目 假设你正在爬楼梯,需要n步你才能到达顶部.但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部? 比如n=3,中不同的方法 返回 3 1 2 3 5 8 13... step[2] = ...
- 【JZOJ3852】【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
DDD Bsny从字典挑出N个单词,并设计了接龙游戏,只要一个单词的最后两个字母和另一个单词的前两个字母相同,那么这两个单词就可以有序的连接起来. Bsny想要知道在所给的所有单词中能否按照上述方式接 ...
- Directx教程(22) 简单的光照模型(1)
原文:Directx教程(22) 简单的光照模型(1) 在前面的教程中,我们在顶点属性中直接给顶点赋颜色,这样生成的三维物体缺乏真实感,如下图中两个立方体,左边的是通过光照生成物体表面颜色的 ...
- PB 级数据处理挑战,Kubernetes如何助力基因分析?
摘要: 一家大型基因测序功能公司每日会产生 10TB 到 100TB 的下机数据,大数据生信分析平台需要达到 PB 级别的数据处理能力.这背后是生物科技和计算机科技的双向支撑:测序应用从科研逐步走向临 ...
- TP3.2的URL重写省略index.php问题
1. 在tp3框架的配置文件里,明确指定了路由的格式,这个配置位于thinkPHP文件夹下的conf文件夹里的convention.php中,修改以下字段 'URL_MODEL' => 2, # ...
- MacOS局域网访问Windows7共享文件
配置步骤 Windows7 进入[控制面板]-[网络和共享中心]-[高级共享设置] 启用网络发现 启用文件和打印机共享 选择要共享的文件或文件夹,点击[共享]-[特定用户] 选择Windows7当前登 ...
- win7 64位下如何安装配置mysql-5.7.4-m14-winx64(安装记录)
1. mysql-5.7.4-m14-winx64.zip下载 官方网站下载地址:http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.17 ...
- bzoj1614 架设电话线
Description Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用. FJ的农场周围分布着N(1 <= N ...
- jQuery show hide方法 二级菜单
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...