POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635
题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]。
一些口胡:
说实话,上次写类似的二维状态最短路Gym 101873C - Joyride - [最短路变形][优先队列优化Dijkstra],我没能把手写二叉堆优化Dijkstra的给写出来。
这次费了点功夫,也算是给写出来了,需要注意的点还是有点多的。而且我终于深刻理解为啥不推荐手写二叉堆了,主要是代码量相比优先队列实在是有点大……
而且耗时好像和优先队列优化Dijkstra没啥差别。
AC代码:
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1e3+;
const int maxm=1e4+;
const int maxc=+; int n,m,q;
int p[maxn]; struct Edge{
int u,v,w;
Edge(int _u=,int _v=,int _w=){u=_u,v=_v,w=_w;}
};
vector<Edge> E;
vector<int> G[maxn];
void init(int l,int r)
{
E.clear();
for(int i=l;i<=r;i++) G[i].clear();
}
void addedge(int u,int v,int w)
{
E.push_back(Edge(u,v,w));
G[u].push_back(E.size()-);
} int d[maxn][maxc],vis[maxn][maxc];
struct Hnode{
int v,r;
Hnode(){}
Hnode(int _v,int _r) {
v=_v, r=_r;
}
};
struct Heap
{
int sz;
Hnode hp[*maxn*maxc];
int pos[maxn][maxc];
void up(int now)
{
while(now>)
{
int par=now>>;
if(d[hp[now].v][hp[now].r]<d[hp[par].v][hp[par].r]) //子节点小于父节点,不满足小顶堆性质
{
swap(hp[par],hp[now]);
swap(pos[hp[par].v][hp[par].r],pos[hp[now].v][hp[now].r]);
now=par;
}
else break;
}
}
void push(Hnode x) //插入权值为x的节点
{
hp[++sz]=x;
pos[x.v][x.r]=sz;
up(sz);
}
Hnode top(){return hp[];}
void down(int now)
{
while((now<<)<=sz)
{
int nxt=now<<;
if(nxt+<=sz && d[hp[nxt+].v][hp[nxt+].r]<d[hp[nxt].v][hp[nxt].r]) nxt++; //取左右子节点中较小的
if(d[hp[nxt].v][hp[nxt].r]<d[hp[now].v][hp[now].r]) //子节点小于父节点,不满足小顶堆性质
{
swap(hp[now],hp[nxt]);
swap(pos[hp[now].v][hp[now].r],pos[hp[nxt].v][hp[nxt].r]);
now=nxt;
}
else break;
}
}
void pop() //移除堆顶
{
hp[]=hp[sz--];
pos[hp[].v][hp[].r]=;
down();
}
inline void clr()
{
sz=;
memset(pos,,sizeof(pos));
}
}H;
int dijkstra(int c,int s,int t)
{
memset(d,0x3f,sizeof(d));
memset(vis,,sizeof(vis)); H.clr();
d[s][]=, H.push((Hnode){s,});
while(H.sz)
{
int u=H.top().v, r=H.top().r; H.pop();
if(u==t) return d[u][r];
if(vis[u][r]) continue;
else vis[u][r]=; if(r<c) {
d[u][r+]=d[u][r]+p[u], H.push((Hnode){u,r+});
}
for(int i=;i<G[u].size();i++)
{
Edge &e=E[G[u][i]]; int v=e.v;
if(r<e.w || vis[v][r-e.w]) continue;
if(d[v][r-e.w]>d[u][r]) {
d[v][r-e.w]=d[u][r];
if(H.pos[v][r-e.w]) H.up(H.pos[v][r-e.w]);
else H.push((Hnode){v,r-e.w});
}
}
}
return INF;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++) scanf("%d",&p[i]);
init(,n);
for(int i=,u,v,w;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
scanf("%d",&q);
for(int i=,c,s,t;i<=q;i++)
{
scanf("%d%d%d",&c,&s,&t);
int ans=dijkstra(c,s,t);
if(ans<INF) printf("%d\n",ans);
else printf("impossible\n");
}
}
在百练上面可以使用pb_ds库,所以用在OpenJ_Bailian 3761 - Full Tank?上交了一发配对堆优化的Dijkstra。
如果想自己写结构体类型放进配对堆的话,还要再写一个专门用来比较结构体的类型,里面要重定义"()"操作符。
AC代码:
#include<bits/stdc++.h>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
const int INF=0x3f3f3f3f;
const int maxn=1e3+;
const int maxm=1e4+;
const int maxc=+; int n,m,q;
int p[maxn]; struct Edge{
int u,v,w;
Edge(int _u=,int _v=,int _w=){u=_u,v=_v,w=_w;}
};
vector<Edge> E;
vector<int> G[maxn];
void init(int l,int r)
{
E.clear();
for(int i=l;i<=r;i++) G[i].clear();
}
void addedge(int u,int v,int w)
{
E.push_back(Edge(u,v,w));
G[u].push_back(E.size()-);
} struct Qnode{
int v;
int d,r;
Qnode(){}
Qnode(int _v,int _d,int _r) {
v=_v, d=_d, r=_r;
}
};
struct Cmp{
bool operator()(const Qnode& a,const Qnode& b)const {
return a.d>b.d;
}
};
typedef __gnu_pbds::priority_queue<Qnode,Cmp,pairing_heap_tag> Heap;
int d[maxn][maxc];
int dijkstra(int c,int s,int t)
{
memset(d,0x3f,sizeof(d)); Heap Q;
Heap::point_iterator id[maxn][maxc]; d[s][]=;
id[s][]=Q.push(Qnode(s,d[s][],));
while(!Q.empty())
{
int u=Q.top().v, r=Q.top().r; Q.pop();
if(u==t) return d[u][r];
if(r<c)
{
d[u][r+]=d[u][r]+p[u];
id[u][r+]=Q.push(Qnode(u,d[u][r+],r+));
}
for(int i=;i<G[u].size();i++)
{
Edge &e=E[G[u][i]]; int v=e.v;
if(r<e.w) continue;
if(d[v][r-e.w]>d[u][r])
{
d[v][r-e.w]=d[u][r];
if(id[v][r-e.w]!=) Q.modify(id[v][r-e.w],Qnode(v,d[v][r-e.w],r-e.w));
else id[v][r-e.w]=Q.push(Qnode(v,d[v][r-e.w],r-e.w));
}
}
}
return INF;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++) scanf("%d",&p[i]);
init(,n);
for(int i=,u,v,w;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
scanf("%d",&q);
for(int i=,c,s,t;i<=q;i++)
{
scanf("%d%d%d",&c,&s,&t);
int ans=dijkstra(c,s,t);
if(ans<INF) printf("%d\n",ans);
else printf("impossible\n");
}
}
POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]的更多相关文章
- POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 Description After going through the receipts from your car trip ...
- POJ 3635 Full Tank? 【分层图/最短路dp】
任意门:http://poj.org/problem?id=3635 Full Tank? Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- Full Tank? POJ - 3635 (bfs | 最短路)
After going through the receipts from your car trip through Europe this summer, you realised that th ...
- POJ 2253 Frogger【最短路变形——路径上最小的最大权】
链接: http://poj.org/problem?id=2253 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22010#probl ...
- poj 3635 Full Tank? ( bfs+dp思想 )
Full Tank? Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5857 Accepted: 1920 Descri ...
- poj 3635 Full Tank? ( 图上dp )
题意: 已知每一个点的加油站的油价单位价格(即点权).每条路的长度(边权). 有q个询问.每一个询问包含起点s.终点e和油箱容量. 问从起点走到终点的最小花费.假设不可达输出impossible,否则 ...
- POJ 1797 Heavy Transportation 最短路变形(dijkstra算法)
题目:click here 题意: 有n个城市,m条道路,在每条道路上有一个承载量,现在要求从1到n城市最大承载量,而最大承载量就是从城市1到城市n所有通路上的最大承载量.分析: 其实这个求最大边可以 ...
- [POJ 3635] Full Tank?
题目 Description 已知每个点的加油站的油价单价(即点权),每条路的长度(边权). 有q个询问,每个询问包括起点s.终点e和油箱容量c. 问从起点走到终点的最小花费.如果不可达输出impos ...
- POJ 2253 Frogger【最短路变形/最小生成树的最大权/最小瓶颈树/A到B多条路径中的最小的最长边】
Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sit ...
随机推荐
- Redis相关技巧
一. 内存占用过大,设置内存最大上限. vi /etc/redis.conf maxmemory 1g maxmemory-policy allkeys-lru (慎用) appendonly yes ...
- 【Windows】Windows中解析DOS的for命令使用
目录结构: contents structure [+] 简介 for /d ... in ... 案例 案例:打印C://根目录下所有的文件夹名称 案例:打印当前路径下,只有1-3个字母的文件夹名 ...
- 文件批量上传-统一附件管理器-在线预览文件(有互联网和没有两种)--SNF快速开发平台3.0
实际上在SNF里使用附件管理是非常简单的事情,一句代码就可以搞定.但我也要在这里记录一下统一附件管理器能满足的需求. 通用的附件管理,不要重复开发,调用尽量简洁. 批量文件上传,并对每个文件大小限制, ...
- JS 日期转换,格式化等常用的函数定义
//判断字符串是否日期格式 function isDate(val) { return new Date(val) != "Invalid Date"; } //日期格式化 fun ...
- 【MongoDB】MongoDb的“not master and slaveok=false”错误及解决方法 mongo连接从库出现问题
链接mongodb报错如下 2016-03-14T16:26:00.912+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok& ...
- matplotlib 学习总结
matplotlib 学习总结 作者:csj更新时间:01.09 email:59888745@qq.com 说明:因内容较多,会不断更新 xxx学习总结: 回主目录:2017 年学习记录和总结 # ...
- 模仿ReentrantLock类自定义锁
简介 临近过年了,没什么需求,今天模仿ReentrantLock自定义写了一个自己锁,在这里记录一下,前提是对AQS原理有所了解,分享给大家 1.自定义锁MyLock package com.jack ...
- File 类的 getCanonicalFile( ) 和 getAbsoluteFile( ) 区别
一.打开java.io.File源码,看下两个方法的区别 getAbsoluteFile public File getAbsoluteFile() { String absPath = getAbs ...
- 创建shell脚本
1.写一个脚本 a) 用touch命令创建一个文件:touch my_script b) 用vim编辑器打开my_script文件:vi my_script c) 用vim编辑器编辑my_script ...
- JVM:从实际案例聊聊Java应用的GC优化
原文转载自美团从实际案例聊聊Java应用的GC优化,感谢原作者的贡献 当Java程序性能达不到既定目标,且其他优化手段都已经穷尽时,通常需要调整垃圾回收器来进一步提高性能,称为GC优化.但GC算法复杂 ...