• L


    题意:有一个帝国在打仗,敌方会搞一些破坏,总共用N个阵地,每个阵地都有一个武力值,当第一地方收到攻击的时候他可以进行求助,当然求助的对象只能是武力值比他高的,如果求助失败就输出 ‘-1’, 求助成功就输出 帮助对象的的下标,如果有多个相同武力值的阵地输出下标最小的那个。
    输入的第一行是N,表示又N个阵地(0到n-1),下面一行输入每个阵地的武力值,接着输入一个M,下面有M行,表示两点可以想通,接着有Q次查询,query 是查询这个点能不能有帮助他的,destroy表示摧毁两点之间的联系,值得注意的是,他所摧毁的一定是存在的路,而输入的时候也没有重复数据(为了是题目简单一些吧)。
    分析:由于是中间有摧毁的步骤,而并查集只能两点链接,不能消除,所以只能倒着处理数据,先把所有能摧毁的全部都不链接,把没有摧毁的链接起来,(可以用扩大第二个数的办法来快速查找路),倒着读的时候遇到摧毁就进行建立,这样可以了,不过还要注意值相等的时候按照下标,就是忘了这点才错了好几次,而且数据之间输出一个空行
    ////////////////////////////////////////////////////////////////

     #include<iostream>

    #include<algorithm>
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<queue>
    #include<stack>
    using namespace std;

    const int maxn = 20005;
    const int BigNum = 10000;

    struct node
    {
        int op, u, v;//op等于1代表查询,等于0代表摧毁
    }data[maxn*3];//保存查询数据

    int f[maxn], val[maxn];
    //为了方便查询,把x值扩大10w倍+y值保存下来,use记录这个路是否被摧毁
    int h[maxn], use[maxn];

    int Find(int x)
    {
        if(f[x] != x)
            f[x] = Find(f[x]);
        return f[x];
    }
    void Union(int u, int v)
    {
        u = Find(u), v = Find(v);

        if(u != v)
        {
            if(val[u] < val[v])
                f[u] = v;
            else if(val[u] > val[v])//写成了两个一样的。。。。
                f[v] = u;
            else if(u < v)
                f[v] = u;
            else
                f[u] = v;
        }
    }

    int main()
    {
        int N, t=0;

        while(scanf("%d", &N) != EOF)
        {
            int i, M, u, v, Q;
            char s[10];

            for(i=0; i<N; i++)
            {
                f[i] = i;
                scanf("%d", &val[i]);
            }

            scanf("%d", &M);

            for(i=0; i<M; i++)
            {
                scanf("%d%d", &u, &v);
                if(u > v)swap(u, v);
                h[i] = u + v*BigNum;
                use[i] = 0;
            }

            sort(h, h+M);

            scanf("%d", &Q);

            for(i=0; i<Q; i++)
            {
                scanf("%s", s);

                if(s[0] == 'd')
                {
                    scanf("%d%d", &u, &v);

                    if(u > v)swap(u, v);
                    data[i].u = u;data[i].v = v;
                    data[i].op = 0;
                    int k = lower_bound(h, h+M, u+v*BigNum) - h;
                    use[k] = 1;
                }
                else
                {
                    scanf("%d", &u);
                    data[i].op = 1, data[i].u = u;
                }
            }

            for(i=0; i<M; i++)
            {
                u = h[i] % BigNum, v = h[i] / BigNum;
                if(use[i] == 0)
                    Union(u, v);
            }

            stack<int>sta;

            for(i=Q-1; i>=0; i--)
            {
                if(data[i].op == 0)
                    Union(data[i].u, data[i].v);
                else
                {
                    u = Find(data[i].u);

                    if(val[u] <= val[data[i].u])
                        sta.push(-1);
                    else
                        sta.push(u);
                }
            }

            if(t++)printf(" ");
            while(sta.size())
            {
                printf("%d ", sta.top());
                sta.pop();
            }
        }

        return 0;
    }
    /*
    5
    1 2 3 4 5
    4
    0 1
    1 2
    2 3
    3 4
    5
    query 0
    query 1
    query 2
    query 3
    query 4
    */
  • 相关阅读:
    IDEA常用快捷指令整理
    Python dict 字典
    内联函数
    【MFC】编辑框 CEdit Ctrl控件自动换行设置
    mysql 多sql文件恢复方案
    Linux: 用64位的系统,能编译32位的程序吗?
    C++ 遍历数组
    工业现场传感器传感器为什么采用电流形式输出?
    【转】电磁阀、电磁铁的工作原理说明
    PCB板强弱电隔离距离不够导致损坏和问题检查记录
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4671954.html
Copyright © 2020-2023  润新知