• PDD----配对堆


    //洛谷P3377,不会配对堆基本思路的请百度
    #include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<cstdlib> #include<algorithm> #include<queue> using namespace std; struct heap { int fa; vector<int>son; int val; }PDD[100010];
    //每个节点存父亲fa(好像没用),儿子son,权值val
    int fa[100010]; int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    //用并查集维护每个点在哪个堆里
    int flag[100010];//每个点有没有被删除 int merge(int a,int b) { a=find(a);b=find(b); if(a==b) return a; if(a>b) swap(a,b); if(PDD[a].val>PDD[b].val) {fa[a]=b;PDD[a].fa=b;PDD[b].son.push_back(a);return b;} else {fa[b]=a;PDD[b].fa=a;PDD[a].son.push_back(b);return a;} }//找出两个元素所在堆的堆顶,合并 void del(int x) { if(flag[x]) {printf("-1 ");return;}//如果被删了,直接退出 x=find(x); flag[x]=1; printf("%d ",PDD[x].val); queue<int>s; int cnt=0;//cnt记录有几个儿子 for(int i=0;i<PDD[x].son.size();i++) { int t=PDD[x].son[i]; PDD[t].fa=t; fa[t]=t;//重置并查集信息(分离点) s.push(t); ++cnt; } if(cnt==0) { PDD[x].fa=0; fa[x]=0; return; } while(cnt>1) { int a=s.front();s.pop(); int b=s.front();s.pop(); s.push(merge(a,b)); --cnt; } int top=s.front();//剩下的就是新根节点 PDD[x].fa=top; fa[x]=top; PDD[x].son.clear();
    //将被删节点fa设为新根,防止路径压缩错误 }
    int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&PDD[i].val); PDD[i].fa=i; fa[i]=i; } for(int i=1;i<=m;i++) { int id; scanf("%d",&id); if(id==1) { int x,y; scanf("%d%d",&x,&y); if(flag[x]==0&&flag[y]==0)merge(x,y); } if(id==2) { int x; scanf("%d",&x); del(x); } } }
  • 相关阅读:
    数组
    mysql优化思路
    mysql_存储过程
    mysql_函数
    mysql_结构
    mysql_触发器
    mysql_变量
    mysql_事务
    mysql总结
    mysql备份
  • 原文地址:https://www.cnblogs.com/wjxgy/p/7774690.html
Copyright © 2020-2023  润新知