1455: 罗马游戏

来源:互联网 发布:凤凰金融 知乎 编辑:程序博客网 时间:2024/06/04 18:01

题目链接

题目大意:集合合并与删去集合内最小值。

题解:并查集维护,然后就是可并堆裸题啦

我的收获:斜堆模板……

#include <iostream>#include <cstdio>using namespace std;#define M 1000005int n,m,fa[M],c[M][2],k[M];bool die[M];int fid(int x){return fa[x]==x?x:fa[x]=fid(fa[x]);}int merge(int x,int y){    if(!x) return y;    if(!y) return x;    if(k[x]>k[y]) swap(x,y);    c[x][1]=merge(c[x][1],y);    fa[c[x][1]]=x;    swap(c[x][0],c[x][1]);    return x;}void uniom(int x,int y){    if(die[x]||die[y]) return ;    int p=fid(x),q=fid(y);    if(p==q) return ;    merge(p,q);}int pop(int x){    if(die[x]) return 0;    int p=fid(x);die[p]=1;    fa[p]=merge(c[p][0],c[p][1]);    fa[fa[p]]=fa[p];    return k[p];}void work(){    int x,y;    char opt[5];    while(m--)    {        scanf("%s%d",opt,&x);        if(opt[0]=='M') scanf("%d",&y),uniom(x,y);        else printf("%d\n",pop(x));    }}void init(){    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%d",&k[i]),fa[i]=i;    scanf("%d",&m);}int main(){    init();    work();    return 0;}
0 0
原创粉丝点击