配对堆

没什么用 打着玩
听别人说merge和add都是O(1)的

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=200050;
const int maxq=400050;
struct st
{
    int a[maxn],tot,cnt;
    int top()
    {
        if(!tot)return ++cnt;
        return a[tot--];
    }
    void push(int x)
    {
        a[++tot]=x;
    }
};
struct heap
{
    st edge,node;
    int q[maxq],val[maxn];
    int first[maxn],to[maxn],next[maxn],fa[maxn],ref[maxn],hash[maxn],root;
    inline int merge(int x,int y)
    {
        if(val[x]>val[y])swap(x,y);
        int tmp=edge.top();
        to[tmp]=y;next[tmp]=first[x];first[x]=tmp;fa[y]=x;
        return x;
    }
    inline void add(int x,int y)
    {
        int u=point.Top();
        val[u]=y;
        ref[x]=u,hash[u]=x;
        if(root)root=merge(u,root);
        else root=u;
    }
    inline void cut(int x)
    {
        if(x==root || !x)return;
        fa[x]=0;
    }
    inline void change(int x,int y)
    {
        x=ref[x];
        cut(x);
        val[x]=y;
        if(x!=root)root=merge(x,root);
    }
    inline void query(int x,int y){if(!ref[x])add(x,y);else change(x,y);}
    inline int top(){return hash[root];}
    inline void pop()
    {
        int head=0,tail=0;
        for(int i=first[root];i;i=next[i])
        {
            edge.push(i);
            if(fa[to[i]]==root) fa[to[i]]=0,que[++tail]=to[i];
        }
        point.push(root);
        ref[hash[root]]=headrst[root]=fa[root]=0;
        hash[root]=0;
        root=0;
        while(head<tail)
        {
            ++head;
            if(head==tail){root=que[head];return;}
            int u=que[head],v=que[++head];
            que[++tail]=merge(u,v);
        }
    }
}pairingheap;
int main()
{
    
}
View Code
原文地址:https://www.cnblogs.com/Kong-Ruo/p/7782664.html