luogu P3378 【模板】堆
luogu P4779 【模板】单源最短路径(标准版)
堆是一个完全二叉树
优先队列(系统自带小根堆)
#include<queue>头文件
q.empty()如果队列为空,则返回true,否则返回false
q.size()返回队列中元素的个数
q.pop()删除队首元素,但不返回其值
q.top()返回具有最高优先级的元素值,但不删除该元素
q.push(x)在基于优先级的适当位置插入新元素x
#include<cstdio> #include<queue> //头文件 using namespace std; int val[200020],dis[100010],vis[200020],head[100010],nxt[200020],to[200020]; int n,m,s,k; struct pot { int x,dis; pot(int _x=0,int _dis=0):x(_x),dis(_dis){} friend bool operator < (pot a,pot b) //重载小于号,可将小根堆变为大跟堆 { return a.dis>b.dis; } }l[200020]; priority_queue<pot> que; //建立一个形式为pot结构体的小根堆 void dijkstra() { for(int i=1;i<=n;i++) dis[i]=2e9; que.push(pot(s,0)); dis[s]=0; while(!que.empty()) { pot now; now=que.top(); que.pop(); if(vis[now.x]) continue; vis[now.x]=true; for(int i=head[now.x];i;i=nxt[i]) { if(dis[to[i]]>dis[now.x]+val[i]) { dis[to[i]]=dis[now.x]+val[i]; que.push(pot(to[i],dis[to[i]])); } } } } void add(int a,int b,int c) { k++; nxt[k]=head[a]; to[k]=b; val[k]=c; head[a]=k; } int main() { int a,b,c; scanf("%d%d%d",&n,&m,&s); for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); } dijkstra(); for(int i=1;i<=n;i++) printf("%d ",dis[i]); return 0; }
手写小根堆
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> int t[1000005]; int n,sum=0; using namespace std; void push(int b) { t[++sum]=b; for(int i=sum,j=i>>1;j;i=j,j=i>>1) { if(t[j]>t[i]) swap(t[j],t[i]); } } void pop() { t[1]=t[sum--]; for(int i=1,j=i<<1;j<=sum;i=j,j=i<<1) { if(j+1<=sum&&t[j+1]<t[j]) j++; if(t[i]<t[j]) break; else swap(t[i],t[j]); } } int main() { scanf("%d",&n); int a,b; for(int i=1;i<=n;i++) { scanf("%d",&a); if(a==1) { scanf("%d",&b); push(b); } if(a==2) printf("%d ",t[1]); if(a==3) pop(); } return 0; }