首页 > 代码库 > [BZOJ 1455]罗马游戏(左偏树+并查集)

[BZOJ 1455]罗马游戏(左偏树+并查集)

Description

罗马皇帝很喜欢玩杀人游戏。 他的军队里面有n个人,每个人都是一个独立的团。最近举行了一次平面几何测试,每个人都得到了一个分数。 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻。他决定玩这样一个游戏。 它可以发两种命令: 1. Merger(i, j)。把i所在的团和j所在的团合并成一个团。如果i, j有一个人是死人,那么就忽略该命令。 2. Kill(i)。把i所在的团里面得分最低的人杀死。如果i这个人已经死了,这条命令就忽略。 皇帝希望他每发布一条kill命令,下面的将军就把被杀的人的分数报上来。(如果这条命令被忽略,那么就报0分)

Solution

比较裸的一道左偏树

#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#define MAXN 1000005using namespace std;int n,m,father[MAXN];bool die[MAXN];struct Node{    int lch,rch,w,d;    Node():lch(0),rch(0),w(0),d(0){}}heap[MAXN];int merge(int x,int y){    if(!x||!y)return x+y;    if(heap[x].w>heap[y].w)swap(x,y);    heap[x].rch=merge(y,heap[x].rch);    if(heap[heap[x].lch].d<heap[heap[x].rch].d)swap(heap[x].lch,heap[x].rch);    heap[x].d=heap[heap[x].rch].d+1;    return x;}int find(int x){    if(x==father[x])return x;    return father[x]=find(father[x]);}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d",&heap[i].w);        father[i]=i;}    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        char opt[3];int x,y;        scanf("%s",opt);        if(opt[0]==M)        {            scanf("%d%d",&x,&y);            if(die[x]||die[y])continue;            int fx=find(x),fy=find(y);            if(fx!=fy)            father[fx]=father[fy]=merge(fx,fy);        }        else        {            scanf("%d",&x);            if(die[x])printf("0\n");            else            {                int fx=find(x);                die[fx]=1;                printf("%d\n",heap[fx].w);                father[fx]=merge(heap[fx].lch,heap[fx].rch);                father[father[fx]]=father[fx];            }        }    }    return 0;} 

 

[BZOJ 1455]罗马游戏(左偏树+并查集)