zoukankan      html  css  js  c++  java
  • bzoj1455&&luogu2713罗马游戏

    罗马游戏

    题目描述

      罗马皇帝很喜欢玩杀人游戏。 他的军队里面有n个人,每个人都是一个独立的团。最近举行了一次平面几何测试,每个人都得到了一个分数。 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻。

      他决定玩这样一个游戏。 它可以发两种命令:

    1. Merger(i, j)。把i所在的团和j所在的团合并成一个团。如果i, j有一个人是死人,那么就忽略该命令。
    2. Kill(i)。把i所在的团里面得分最低的人杀死。如果i这个人已经死了,这条命令就忽略。

      皇帝希望他每发布一条kill命令,下面的将军就把被杀的人的分数报上来。(如果这条命令被忽略,那么就报0分)

    输入输出格式

    输入格式:

      第一行一个整数n(1<=n<=1000000)。n表示士兵数,m表示总命令数。

      第二行n个整数,其中第i个数表示编号为i的士兵的分数。(分数都是[0..10000]之间的整数)

      第三行一个整数m(1<=m<=100000) 第3+i行描述第i条命令。命令为如下两种形式: 1. M i j 2. K i

    输出格式:

      如果命令是Kill,对应的请输出被杀人的分数。(如果这个人不存在,就输出0)

    输入输出样例

    输入样例:
        5
        100 90 66 99 10
        7
        M 1 5
        K 1
        K 1
        M 2 3
        M 3 4
        K 5
        K 4
    

      

    输出样例:
        10
        100
        0
        66
    

      分析:很明显这是一道可并堆的经典题目,题目字面翻译过来就是合并小根堆,并且查询最小值后删除最小值,比较简单,类似于板子题。

    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    int dis[1000001];
    int num[1000001];
    int son[1000001][2];
    int fa[1000001];
    bool kill[1000001];
    int n,m;
    int find(int p)
    {
        if(fa[p]==0) return 0;
        return (fa[p]==p)?p:fa[p]=find(fa[p]);
    }
    int merge(int x,int y)
    {
        if(!x) return y;
        if(!y) return x;
        if(num[x]>num[y]) swap(x,y);
        son[x][1]=merge(son[x][1],y);
        if(dis[son[x][1]]>dis[son[x][0]])
            swap(son[x][1],son[x][0]);
        dis[x]=dis[son[x][1]]+1;
        return x;
    }
    int main()
    {
        dis[0]=-1;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&num[i]),fa[i]=i;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            char kind[2];
            scanf("%s",kind);
            if(kind[0]=='M')
            {
                scanf("%d%d",&a,&b);
                if(kill[a]||kill[b]) continue;
                a=find(a),b=find(b);
                if(a!=b) fa[a]=fa[b]=merge(a,b);
            }
            else
            {
                scanf("%d",&a);
                if(kill[a])
                {
                    printf("0
    ");
                    continue;
                }
                int rt;
                printf("%d
    ",num[rt=find(a)]);
                kill[rt]=true;
                b=son[rt][0],a=son[rt][1];
                fa[rt]=fa[a]=fa[b]=merge(a,b);
            }
        }
    }
    

      

  • 相关阅读:
    根据百度API获得经纬度,然后根据经纬度在获得城市信息
    Map实现java缓存机制的简单实例
    JMS学习(七)-ActiveMQ消息的持久存储方式之KahaDB存储
    JMS学习(六)-ActiveMQ的高可用性实现
    排列与组合的一些定理
    带权图的最短路径算法(Dijkstra)实现
    JMS学习(六)--提高非持久订阅者的可靠性 以及 订阅恢复策略
    JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系
    分布式系统理论之两阶段提交协议
    自定义栈的实现及使用两个栈模拟队列
  • 原文地址:https://www.cnblogs.com/yangsongyi/p/8893005.html
Copyright © 2011-2022 走看看