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 ...
随机推荐
- 使用 bibtex4word 实现在 office word 中管理并插入参考文献
使用 bibtex4word 实现在 office word 中管理并插入参考文献, 简单的步骤流程如下: 1. 下载bibtex4word.zip (无需安装): 下载地址: http://www ...
- android的activity被杀死后如何重启
最近公司的大屏展示机器人上的程序运行时间长了,比如五天,十天会出现偶尔的崩溃,查日志可能是内存溢出或者是ndk层的错误,这种错误一时也不太好查找,但是产品那边有个要求就是程序退出了一定要能重启,能抓日 ...
- 100个MySQL 的调节和优化的提示
100个MySQL 的调节和优化的提示 MySQL是一个功能强大的开源数据库.随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限.这里是101条调节和优化MySQL安装的技巧. ...
- 一道简单的HashMap面试题所想到的...
前言 看到一个JDK1.7和JDK1.8中关于HashMap的一个面试题: JDK1.7和1.8中HashMap中链表的插入的方式有什么不同? 原以为自己对HashMap的源码理解的还算可以了,应该足 ...
- 转发-基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现
基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现 概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有 ...
- [k8s]k8s-ceph-statefulsets-storageclass-nfs 有状态应用布署实践
k8s stateful sets storageclass 有状态应用布署实践v2 Copyright 2017-05-22 xiaogang(172826370@qq.com) 参考 由于网上的文 ...
- [docker]docker4种网络最佳实战
参考: http://hicu.be/docker-container-network-types docker默认3中网络类型 参考: https://docs.docker.com/engine/ ...
- 重定向如何携带cookie
起因 最近在做微信开放平台,需要给第三方入住,而且入住方都有自己的二级域名.做过微信开发的人都知道,坑爹的是微信并不支持这种二级域名的方式,所以用一个域名专门来处理. 问题 然后由于采用了一个专门的域 ...
- Java多线程系列——线程池原理之 ThreadPoolExecutor
ThreadPoolExecutor 简介 ThreadPoolExecutor 是线程池类. 通俗的讲,它是一个存放一定数量线程的线程集合.线程池允许多个线程同时运行,同时运行的线程数量就是这个线程 ...
- mac通过路径找到对应的文件夹
在finder中 command + shift + G 跳出窗口中输入指定的路径,即可到达.