您的位置:首页 > 其它

【BZOJ1455】罗马游戏 可并堆

2015-03-21 09:36 225 查看

链接:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/44513511");
}


题解:

可并堆:

其实它只是个函数,而不是数据结构,它的数据结构只是“堆”?

可并的随机堆才算一个?

两个堆合并时,对比大小决定谁是父亲,然后劣的和优的 的子再递归进行比较,直到一头为空(无法也不用再比较时),能满足正常插入就可以保证二叉的性质时停止。

代码:

可并随机堆(随机挂到某子上)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1001000
#define inf 0x3f3f3f3f
using namespace std;
struct Merge_Heap
{
    int son
[2],val
;
    bool be_killed
;

    int fa
;
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    void init(int n)
    {
        val[0]=inf;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&val[i]);
            fa[i]=i;
        }
    }
    int merge(int x,int y) // 小根随机可并堆
    {
        if(val[x]>val[y])swap(x,y);
        if((x&&y)==0)return x;
        int k=rand()&1;
        son[x][k]=merge(son[x][k],y);
        return x;
    }
    void kill()
    {
        int x;
        scanf("%d",&x);
        if(be_killed[x])
        {
            puts("0");
            return ;
        }
        x=find(x);
        be_killed[x]=1;
        printf("%d\n",val[x]);
        int k=merge(son[x][0],son[x][1]);
        if(k)fa[x]=fa[son[x][0]]=fa[son[x][1]]=k;
    }
    void battle()
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if(be_killed[x]||be_killed[y])return ;
        if(find(x)==find(y))return ;
        fa[fa[x]]=fa[fa[y]]=merge(fa[x],fa[y]);
    }
}heap;
int n,m;
char opt[5];
int main()
{
//  freopen("test.in","r",stdin);

    srand(252503);
    int i,k;
    scanf("%d",&n);
    heap.init(n);

    for(scanf("%d",&m);m--;)
    {
        scanf("%s",opt);
        if(opt[0]=='K')heap.kill();
        else heap.battle();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: