• 斐波那契堆模板


    题目

    测试题目传送门 emmm,其实只写了一部分函数(就这还折腾了整整半天 ),其他的留坑吧= =,而且也没用指针写,常数也很大QAQ

    Code

    //By zuiyumeng
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define Re register
    #define Ms(a,b) memset((a),(b),sizeof(a))
    #define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
    #define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
    using namespace std;
    
    inline int read() { 
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
        while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
        return x*f;
    }
    
    const int N=1e5+10;
    int n,m;
    int fdeg[N],fa[N];
    bool vis[N];
    struct Node{
        int key,degree,fa,son,left,right;
        bool deld;//该题特殊要求
    }nd[N];
    struct Heap{
        int min,n;
    }hep[N];
    
    void insrt(int now,int u) {
        Node &x=nd[u]; Heap &h=hep[now];
        x.fa=0;
        if(!h.min) {
            x.left=x.right=u;
            h.min=u;
        } else {
            Node &y=nd[h.min],&z=nd[y.right];
            x.left=z.left; x.right=y.right;
            y.right=z.left=u;
            if(y.key>x.key||(y.key==x.key&&h.min>u)) h.min=u;
            // ||后为该题特殊要求
        }
        h.n++;
    }
    
    Heap merge(int u,int v) {
        Heap &h1=hep[u],&h2=hep[v],h;
        Node &a1=nd[h1.min],&b1=nd[a1.right];
        Node &a2=nd[h2.min],&b2=nd[a2.left];
        b1.left=a2.left,b2.right=a1.right;
        a1.right=h2.min,a2.left=h1.min;
        h.min=h1.min;
        if(!h1.min || (h2.min&&a2.key<a1.key)) h.min=h2.min;
        h.n=h1.n+h2.n;
        return h;
    }
    
    void link(int now,int u,int v) {
        Node &x=nd[u],&y=nd[v];
        nd[y.left].right=y.right;
        nd[y.right].left=y.left;
        if(x.son) {
            Node &a=nd[x.son],&b=nd[a.right];
            y.left=x.son,y.right=a.right;
            a.right=v,b.left=v;
        } else {
            x.son=v;
            y.left=y.right=v;
        }
        y.fa=u; x.degree++;
    }
    
    void consoldate(int now) {
        Ms(fdeg,0);Ms(vis,0);
        Heap &h=hep[now];
        int cur=h.min;
        while(!vis[cur]) {
            int d=nd[cur].degree,nxt=nd[cur].right; vis[cur]=1;
            while(fdeg[d]) {
                Node &y=nd[fdeg[d]],&x=nd[cur];
                if(x.key>y.key||(x.key==y.key&&cur>fdeg[d])) swap(cur,fdeg[d]);
                // ||后为该题特殊要求
                link(now,cur,fdeg[d]);
                fdeg[d]=0; d++;
            }
            fdeg[d]=cur;
            cur=nxt; 
        }
        h.min=0;
        Fo(i,0,ceil(log2((double)h.n))+1) if(fdeg[i]) {
            int u=fdeg[i]; Node &x=nd[u];
            insrt(now,u); h.n--;
        }
    }
    
    int deleteMin(int now) {
        Heap &h=hep[now];
        Node &x=nd[h.min];
        if(!h.min) return 0;
        int cur=x.son;
        Fo(i,1,x.degree) {
            int nxt=nd[cur].left;
            insrt(now,cur); h.n--;
            nd[cur].fa=0;
            cur=nxt;
        }
        nd[x.left].right=x.right;
        nd[x.right].left=x.left;
        x.deld=1; x.son=0;
        if(x.right==h.min) h.min=0;
        else { 
            h.min=x.right;
            consoldate(now);
        }
        h.n--;
        return x.key;
    }
    
    int getro(int x) {return fa[x]=fa[x]==x?x:getro(fa[x]);}//这个题得用并查集
    
    int main() {
        n=read();m=read();
        Fo(i,1,n) nd[i].key=read(),insrt(i,i),fa[i]=i;
        Fo(i,1,m) { 
            int opt=read();
            if(opt==1) {
                int x=read(),y=read();
                if(nd[x].deld||nd[y].deld) continue;
                int rx=getro(x),ry=getro(y);
                if(rx==ry) continue;
                if(rx>ry) swap(rx,ry);
                hep[rx]=merge(rx,ry);
                fa[ry]=rx;
            } else {
                int x=read();
                if(nd[x].deld) {cout<<"-1"<<endl;continue;}
                int rx=getro(x); 
                cout<<deleteMin(rx)<<endl;
            }
        }
        return 0;
    }
    
    本文版权归作者所有,未经允许不得转载。
  • 相关阅读:
    搭建VueMint-ui框架
    vue项目创建
    jQuery选择器总结
    位运算
    Hash哈希
    并发编程(六)并发容器
    并发编程(五)AQS
    并发编程(四)显示锁
    Java中的几种代码块
    并发编程(三)原子操作CAS
  • 原文地址:https://www.cnblogs.com/zuiyumeng/p/13545812.html
Copyright © 2020-2023  润新知