L - Connections in Galaxy War - zoj 3261

题意:有一个帝国在打仗,敌方会搞一些破坏,总共用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("\n");
        while(sta.size())
        {
            printf("%d\n", 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
*/
posted @ 2015-07-23 22:15  无忧望月  阅读(274)  评论(0编辑  收藏  举报
levels of contents