luogu P3378 【模板】堆

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;    
}
原文地址:https://www.cnblogs.com/QAQq/p/10301035.html