用pb_ds的优先队列来做dijkstra。。据说noip能用哟。

先来篇关于仿函数的文章

由于pb_ds支持由迭代器访问元素,并且push操作会返回一个迭代器,merge操作会更新迭代器,相当于帮你实现了根据编号找元素的功能(每个元素对应一个迭代器)。但是由于dijkstra在取出堆顶元素以后还要知道堆顶元素的编号,于是我们可以自己搞一个结构体,然后弄一个仿函数。。这样就完成了。

 #include <cstdio>
#include <cstring>
#include <functional>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std; const int maxn=, maxm=5e6+, INF=; struct heap_node{
int value, id;
}; struct cmp{
bool operator() (heap_node a, heap_node b){
return a.value>b.value;
}
}; __gnu_pbds::priority_queue<heap_node, cmp> heap;
__gnu_pbds::priority_queue<heap_node, cmp>::point_iterator p[maxn]; struct Edge{
int to, next, v;
}; class Graph{
private:
int n, cntedge;
int fir[maxn];
Edge edge[maxm], link[maxn];
public:
Graph(){
n=, cntedge=;
memset(fir, , sizeof(fir));
memset(edge, , sizeof(edge));
} void addedge(int x, int y, int z){
++cntedge;
edge[cntedge].to=y;
edge[cntedge].v=z;
edge[cntedge].next=fir[x];
fir[x]=cntedge;
return;
} Edge *get_link(int x){
int nowedge, nowson, cntlink=;
for (nowedge=fir[x]; nowedge;
nowedge=edge[nowedge].next){
nowson=edge[nowedge].to;
++cntlink;
link[cntlink]=edge[nowedge];
}
link[].v=cntlink;
return link;
} }; int n, m, s;
int dis[maxn];
Graph g; int main(){
for (int i=; i<maxn; ++i)
dis[i]=INF;
scanf("%d%d%d", &n, &m, &s);
int f, gg, w;
for (int i=; i<m; ++i){
scanf("%d%d%d", &f, &gg, &w);
g.addedge(f, gg, w);
}
heap_node ht;
for (int i=; i<=n; ++i){
ht.id=i, ht.value=INF;
p[i]=heap.push(ht);
}
dis[s]=;
ht.id=s, ht.value=;
heap.modify(p[s], ht);
int now, nowson;
Edge *link;
for (int i=; i<n; ++i){
ht=heap.top();
heap.pop();
if (ht.value==INF) break;
now=ht.id;
link=g.get_link(now);
for (int i=; i<=link[].v; ++i){
nowson=link[i].to;
if (dis[now]+link[i].v<dis[nowson]){
dis[nowson]=dis[now]+link[i].v;
ht.id=nowson, ht.value=dis[nowson];
heap.modify(p[nowson], ht);
}
}
}
for (int i=; i<=n; ++i){
printf("%d ", dis[i]);
}
return ;
}

pb_ds的优先队列实现dijkstra的更多相关文章

  1. poj 1511 优先队列优化dijkstra *

    题意:两遍最短路 链接:点我 注意结果用long long #include<cstdio> #include<iostream> #include<algorithm& ...

  2. POJ 1511 Invitation Cards (ZOJ 2008) 使用优先队列的dijkstra

    传送门: http://poj.org/problem?id=1511 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1008 ...

  3. hdu 1142 用优先队列实现Dijkstra

    之前很认真地看了用优先队列来实现Dijkstra这块,借鉴了小白书上的代码模板后,便拿这道题来试试水了.这道题的大意就是问你从地点1到地点2有多少条满足条件的路径(假设该路径经过 1->...- ...

  4. POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 Description After going through the receipts from your car trip ...

  5. HDU 1535 Invitation Cards(逆向思维+邻接表+优先队列的Dijkstra算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1535 Problem Description In the age of television, n ...

  6. Gym 101873C - Joyride - [最短路变形][优先队列优化Dijkstra]

    题目链接:http://codeforces.com/gym/101873/problem/C 题意: 这是七月的又一个阳光灿烂的日子,你决定和你的小女儿一起度过快乐的一天.因为她真的很喜欢隔壁镇上的 ...

  7. 隐式Dijkstra:在状态集合中用优先队列求前k小

    这种技巧是挺久以前接触的了,最近又突然遇到几道新题,于是总结了一下体会. 这种算法适用的前提是,标题所述的"状态集合"大到不可枚举(否则枚举就行了qaq) ...

  8. dijkstra算法与优先队列

    这是鄙人的第一篇技术博客,作为算法小菜鸟外加轻度写作障碍者,写技术博客也算是对自己的一种挑战和鞭策吧~ 言归正传,什么是dijkstra算法呢? -dijkstra算法是一种解决最短路径问题的简单有效 ...

  9. POJ 1511 Invitation Cards(单源最短路,优先队列优化的Dijkstra)

    Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 16178   Accepted: 526 ...

随机推荐

  1. json 文件解析与应用

    第一步:首先弄一个 json 文件   我这里成为 config.json 内容如下 { ": { , "desc":"中华人民共和国" }, &qu ...

  2. error: ‘errno’ was not declared in this scope

    问题: 将一个c文件改为cpp文件,其中的perror()改用C++中的std::cerr << strerror(error) << std::endl;来替换. 重新编译文 ...

  3. luogu1336 最佳课题选择

    背包问题加强版orz #include<iostream> #include<cstdio> #include<cmath> #include<cstring ...

  4. ACM学习历程—HDU4415 Assassin’s Creed(贪心)

    Problem Description Ezio Auditore is a great master as an assassin. Now he has prowled in the enemie ...

  5. BZOJ1345:[Baltic2007]序列问题

    浅谈栈:https://www.cnblogs.com/AKMer/p/10278222.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?id ...

  6. rsync同步文件,排除多个文件/目录

    使用rsync -aP --exclude=upload 只能排除upload文件/目录.如果要排除多个文件/目录,怎么办?  那只能建一个exclude.list,里面填写要排除的目录(一行一个文件 ...

  7. C/C++文件读写操作总结

    本文主要从两方面介绍读写文件操作,一个是C,另一个是C++. 一.基于C的文件操作. 在ANSI C中对文件操作有两种方式,一种是流式文件操作,另一种是I/O文件操作.下面分别介绍. 1.流式文件操作 ...

  8. 【转】 Pro Android学习笔记(三八):Fragment(3):基础小例子-续

    目录(?)[-] Step 2实现Fragment指定调用类TitleFragment onInflate和onAttach onCreate和onCreateView onActivityCreat ...

  9. Scala总结

    Scala总结 ===概述 scala是一门以Java虚拟机(JVM)为目标运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言. scala是纯粹的面向对象的语言.java虽然是面 ...

  10. Python-IO模式介绍

    事件驱动模型:有个事件队列,把事件放到队列里,然后循环这个队列,取出事件执行 5种IO模式: 阻塞 I/O(blocking IO) 非阻塞 I/O(nonblocking IO) I/O 多路复用( ...