[学习笔记]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) 国庆休假前学习了 ...
随机推荐
- 大数据技术之Zookeeper
第1章 Zookeeper入门 1.1 概述 Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目. 1.2 特点 1.3 数据结构 1.4 应用场景 提供的服务包括:统 ...
- poj3532 Round Numbers
题意:给出l.r,求区间[l,r]内二进制中0的个数大于等于1的个数的数字有多少个. 简单的数位dp. //Serene #include<algorithm> #include< ...
- docker 与host互传文件
docker 的cp命令可以从容器往外复制,也可以从本机复制的容器. docker cp 文件路径 容器id:/容器目录 docker help cp Usage: docker cp [OPT ...
- hdu 3536【并查集】
hdu 3536 题意: 有N个珠子,第i个珠子初始放在第i个城市.有两种操作: T A B:把A珠子所在城市的所有珠子放到B城市. Q A:输出A珠子所在城市编号,该城市有多少个珠子,该珠子转移了 ...
- [转]The Curse of Dimensionality(维数灾难)
原文章地址:维度灾难 - 柳枫的文章 - 知乎 https://zhuanlan.zhihu.com/p/27488363 对于大多数数据,在一维空间或者说是低维空间都是很难完全分割的,但是在高纬空间 ...
- jQuery show hide方法 二级菜单
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SQL语法之DDL和DML
SQL语法之DDL和DML DDL数据库定义语言 create 创建 alter 修改 drop 删除 drop和delete的区别 truncate DML 数据操作语言 insert ...
- C# —— 访问修饰符
1.public 公有的,任何代码均可以访问,应用于所有类或成员. 2.internal 内部的,只能在当前程序集中使用,应用于所有类或成员. 3.protected internal 受保护的内部成 ...
- iOS-CoreLocation:无论你在哪里,我都要找到你!
作者:@翁呀伟呀 授权本站转载 CoreLocation 1.定位 使用步骤: 创建CLLocationManager示例,并且需要强引用它 设置CLLocationManager的代理,监听并获取所 ...
- iOS如何才能在招聘中表现得靠谱?
http://www.cocoachina.com/programmer/20150707/12414.html 近一年内陆续面试了不少人了,从面试者到面试官的转变让我对 iOS 招聘有了更多的感受. ...