博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1975 SDOI2010 魔法猪学院 A*k短路
阅读量:5776 次
发布时间:2019-06-18

本文共 2545 字,大约阅读时间需要 8 分钟。

题目大意:给定一个值E 求起点到终点的最多条路径 使长度之和不超过E

k短路的A*算法……每一个点有一个估价函数=g[x]+h[x] 当中g[x]是从源点出发已经走了的长度 h[x]是从这个点到汇点的最短路

首先先在反图上跑一遍SPFA求出每一个点的h[x],然后将源点的g[x]+h[x]增加堆 每次取出堆顶时将堆顶的g[x]向所连接的边扩展 第k次取出汇点即是答案

当中有一个剪枝就是当第k+1次取出某个点时不继续拓展 防止MLE 可是这里k未知 我们能够对k进行估价处理 初始k=floor(E/最短路长度) 然后每次取出汇点时更新k k=cnt[n]+floor(E/当前路径长度)

比較丧病的是这题卡priority_queue……这东西的内存是手写堆的二倍 因为卡内存 所以会挂 能够手写堆 我写了可并堆+垃圾回收……

#include
#include
#include
#include
#include
#define M 5050using namespace std;struct abcd{ int pos; double g,h; bool operator < (const abcd &x) const { return g + h < x.g + x.h ; }};struct Heap{ abcd num; Heap *ls,*rs; void* operator new (size_t size,int pos,double g,double h); void operator delete (void* p);}*root,*mempool,*C;struct edge{ int to,next; double f;}table[400400];int head[M],tot=1;bool flag;queue
bin;int n,m,k,ans,cnt[M];double e,f[M];void* Heap :: operator new (size_t size,int pos,double g,double h){ if( !bin.empty() ) { Heap *re=(Heap*)bin.front(); bin.pop(); re->num.pos=pos; re->num.g=g; re->num.h=h; re->ls=re->rs=0x0; return re; } if(C==mempool) { C=new Heap[1<<15]; mempool=C+(1<<15); } C->num.pos=pos; C->num.g=g; C->num.h=h; C->ls=C->rs=0x0; return C++;}void Heap :: operator delete (void *p){ bin.push(p);}Heap* Merge(Heap *x,Heap *y){ if(!x) return y; if(!y) return x; if( y->num < x->num ) swap(x,y); if(flag^=1) x->ls=Merge(x->ls,y); else x->rs=Merge(x->rs,y); return x;}inline void Insert(int pos,double g,double h){ root=Merge(root,new (pos,g,h) Heap);}inline void Pop(){ delete root; root=Merge(root->ls,root->rs);}void Add(int x,int y,double z){ table[++tot].to=y; table[tot].f=z; table[tot].next=head[x]; head[x]=tot;}void SPFA(){ static int q[1<<16]; static unsigned short r,h; static bool v[M]; int i; memset(f,0x42,sizeof f); f[n]=0;q[++r]=n; while(r!=h) { int x=q[++h];v[x]=0; for(i=head[x];i;i=table[i].next) if( i&1 && f[table[i].to]>f[x]+table[i].f ) { f[table[i].to]=f[x]+table[i].f; if(!v[table[i].to]) v[table[i].to]=1,q[++r]=table[i].to; } }}void A_Star(){ int i; k=static_cast
(e/f[1])+1; Insert(1,0,f[1]); while(root) { abcd x=root->num;Pop(); if( ++cnt[x.pos]>k ) continue; if(x.pos==n) { if(e-x.g<0) return ; e-=x.g;++ans; k=cnt[n]+static_cast
(e/x.g)+1; } for(i=head[x.pos];i;i=table[i].next) if(~i&1) Insert(table[i].to,x.g+table[i].f,f[table[i].to]); }}int main(){ int i,x,y; double z; cin>>n>>m>>e; for(i=1;i<=m;i++) { scanf("%d%d%lf",&x,&y,&z); Add(x,y,z); Add(y,x,z); } SPFA(); A_Star(); cout<
<

转载地址:http://iehux.baihongyu.com/

你可能感兴趣的文章
云南去年有望实现151万贫困人口净脱贫
查看>>
Java架构师面试题系列整理(大全)
查看>>
延伸产业链 中国产粮大省向“精深”问发展
查看>>
消费贷用户70%月收入低于5000元 80、90后是主要人群
查看>>
2018年内蒙古外贸首次突破1000亿元
查看>>
CTOR有助于BCH石墨烯技术更上一层楼
查看>>
被遗忘的CSS
查看>>
Webpack中的sourcemap以及如何在生产和开发环境中合理的设置sourcemap的类型
查看>>
做完小程序项目、老板给我加了6k薪资~
查看>>
java工程师linux命令,这篇文章就够了
查看>>
关于React生命周期的学习
查看>>
webpack雪碧图生成
查看>>
搭建智能合约开发环境Remix IDE及使用
查看>>
Spring Cloud构建微服务架构—服务消费基础
查看>>
RAC实践采坑指北
查看>>
runtime运行时 isa指针 SEL方法选择器 IMP函数指针 Method方法 runtime消息机制 runtime的使用...
查看>>
LeetCode36.有效的数独 JavaScript
查看>>
Scrapy基本用法
查看>>
PAT A1030 动态规划
查看>>
自制一个 elasticsearch-spring-boot-starter
查看>>