码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1455 罗马游戏

时间:2016-05-07 16:35:29      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:

两点注意:

首先,pop一个点now,设fath[now]为当前堆顶节点。

其次,这题不保证两军团是否merge过。

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000500
using namespace std;
int n,m,w[maxn],tree[maxn][3],fath[maxn],x,y,dis[maxn];
char s[3];
bool vis[maxn];
int find(int x)
{
    if(x!=fath[x])
        fath[x]=find(fath[x]);
    return fath[x];
}
void pushup(int x)
{
    int ls=tree[x][1],rs=tree[x][2];
    if (dis[ls]<dis[rs]) swap(tree[x][1],tree[x][2]);
    if (rs==0) dis[x]=0;
    else dis[x]=dis[rs]+1;
}
int merge(int a,int b)
{
    if (a==0) return b;
    if (b==0) return a;
    if (w[a]>w[b]) swap(a,b);
    tree[a][2]=merge(tree[a][2],b);
    fath[tree[a][2]]=a;
    pushup(a);
    return a;
}
void pop(int x)
{
    int ls=tree[x][1],rs=tree[x][2];
    tree[x][1]=tree[x][2]=dis[x]=0;
    fath[ls]=ls;fath[rs]=rs;
    int regis=merge(ls,rs);
    fath[x]=regis;
}
void work1()
{
    scanf("%d",&x);
    if (vis[x]) printf("0\n");
    else
    {
        int now=find(x);
        printf("%d\n",w[now]);
        vis[now]=true;
        pop(now);
    }
}
void work2()
{
    int regis;
    scanf("%d%d",&x,&y);
    if ((vis[x])||(vis[y])) return;
    int f1=find(x),f2=find(y);
    if (f1!=f2) 
        regis=merge(f1,f2);
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&w[i]);    
        fath[i]=i;
    }
    scanf("%d",&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%s",s);
        if (s[0]==K) work1();
        else work2();
    }
    return 0;
}

 

BZOJ 1455 罗马游戏

标签:

原文地址:http://www.cnblogs.com/ziliuziliu/p/5468400.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!