Connections in Galaxy War----zoj3261

题目链接:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261

题意:有n个星球编号为0—n-1;能量分别为p[i];有m句话,每句话输入a,b表示星球a和星球b可以相通的;

但是由于银河之战,破坏了一些通道

接下来有Q句话:destroy a b代表ab之间的通道被破坏;

        query a代表求a可以向哪个星球求助,并输出编号,如果没有就输出-1;

各个星球只像能量值比自己大的星球求助,而且是尽量找到最大能量值的星球求助。

如果有多个能量值一样的星球可以求助,则找编号小的。

思路:

   输入时记录每一条边

        记录每一个操作和销毁的边。

        输入结束后先用并查集加入所有没有被销毁的边

        然后再逆序操作记录结果,此时遇到 destroy 则加入销毁的边 ,遇到 query 直接查找即可。

         最终逆序输出结果。

   不同的测试数据有空行。

 

#include<stdio.h>

#include<string.h>

#include<iostream>

#include<algorithm>

#include<math.h>

#include<map>

#define N 50010

#define INF 0xfffffff

using namespace std;



struct node

{

    int op,x,y;// 1代表查询,2代表破坏;

} a[N],b[N];



int f[N], p[N], n, m, ans[N];



map<int,int> maps[N];



int Find(int x)

{

    if(x != f[x])

        f[x] = Find(f[x]);

    return f[x];

}



void Union(int x, int y)

{

    int px = Find(x);

    int py = Find(y);

    if(p[px] > p[py])

        f[py] = px;

    else if(p[px] < p[py])

        f[px] = py;

    else

    {

        if(px <= py)

            f[py] = px;

        else

            f[px] = py;

    }

}

void Init()

{

    int i;

    memset(a, 0, sizeof(a));

    memset(b, 0, sizeof(b));

    for(i=0; i<= n;i++)

    {

        maps[i].clear();

        f[i] = i;

        p[i] = 0;

    }

}

int main()

{

    char str[20];

    int i, j, y, x, Q, flag=0;

    while(scanf("%d", &n)!=EOF)

    {

        Init();

        for(i=0; i<n; i++)

            scanf("%d", &p[i]);

        scanf("%d", &m);

        for(i=0; i<m; i++)

        {

            scanf("%d%d", &x, &y);

            if(x > y) swap(x, y);

            b[i].x = x;

            b[i].y = y;

            maps[x][y] = 1;//代表x和y之间的通道存在;

        }



        scanf("%d", &Q);

        for(i=0; i<Q; i++)

        {

            scanf("%s", str);

            if(str[0] == 'q')

            {

                scanf("%d", &x);

                a[i].op = 1;

                a[i].x = x;

            }

            else

            {

                scanf("%d %d", &x, &y);

                if(x > y) swap(x, y);

                maps[x][y] = 0;//x和y之间的路没路;

                a[i].op = 2;

                a[i].x = x;

                a[i].y = y;

            }

        }

        for(i=0; i<m; i++)//把相关联的放到一起;

        {

            if(maps[b[i].x][b[i].y]==1)

                Union(b[i].x, b[i].y);

        }

        j=0;

        for(i=Q-1; i>=0; i--)//逆序处理每个操作;

        {

            if(a[i].op == 1)

            {

                int px = Find(a[i].x);

                if(p[px] > p[a[i].x])

                    ans[j++] = px;

                else

                    ans[j++] = -1;

            }

            else if(a[i].op == 2)

                Union(a[i].x, a[i].y);

        }

        if(flag==0)

            flag=1;

        else

            printf("\n");

        for(i=j-1; i>=0; i--)

            printf("%d\n", ans[i]);



    }

    return 0;

}
View Code

 

你可能感兴趣的:(Connection)