zoukankan      html  css  js  c++  java
  • zoj 3261 Connections in Galaxy War(并查集逆向加边)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261

    题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现在发生战争,有一些联系通道会被摧毁,而一些星球会通过还没有被摧毁的联系通道直接或者间接联系能够联系到的武力值最高的星球求救,如果有多个武力值都为最高的,那就联系一个编号最小的。现在给出一系列求救和摧毁的序列,一次执行,并对于每一个求救指令寻找合适的求救星球编号,如果没有可以求救的则输出 -1

    这是一道启发题,有时候正这困难倒着反倒简单。

    怎么说,链接好然后断开链接并不是简简单单就能实现的要么复杂度巨高要么就是不存在的。

    所以还不如直接要断开的直接都不连,倒着来遇到要断开的位置再连上,这样就是简单的并查集了

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <map>
    using namespace std;
    const int M = 5e4 + 10;
    int n , m , q , val[M] , f[M] , pos[M] , num[M] , ans[M];
    struct TnT {
        int x , y , z;
    }T[M] , node[M];
    bool vis[M];
    map<int , int>mmp[M];
    int find(int x) {
        if(x == f[x])
            return x;
        return f[x] = find(f[x]);
    }
    void Union(int x , int y) {
        int a = find(x) , b = find(y);
        if(a != b) {
            f[a] = b;
            if(num[b] < num[a]) {
                num[b] = num[a];
                pos[b] = pos[a];
            }
            else if(num[b] == num[a]) {
                if(pos[a] < pos[b]) {
                    pos[b] = pos[a];
                }
            }
        }
    }
    int main() {
        int u , v;
        bool first = true;
        char cp[20];
        while(scanf("%d" , &n) != EOF) {
            if(first)
                first = false;
            else
                printf("
    ");
            for(int i = 0 ;  i < n ; i++) {
                scanf("%d" , &val[i]);
                f[i] = i , pos[i] = i , num[i] = val[i];
                mmp[i].clear();
            }
            scanf("%d" , &m);
            for(int i = 1 ; i <= m ; i++) {
                scanf("%d%d" , &u , &v);
                if(u > v) {
                    int tmp = u;
                    u = v;
                    v = tmp;
                }
                T[i].x = u;
                T[i].y = v;
                mmp[u][v] = i;
                vis[i] = false;
            }
            scanf("%d" , &q);
            for(int i = 1 ; i <= q ; i++) {
                scanf("%s" , cp);
                if(cp[0] == 'q') {
                    scanf("%d" , &node[i].x);
                    node[i].z = 1;
                }
                else {
                    scanf("%d%d" , &u , &v);
                    node[i].z = 2;
                    if(u > v) {
                        int tmp = u;
                        u = v;
                        v = tmp;
                    }
                    node[i].x = u , node[i].y = v;
                    vis[mmp[u][v]] = true;
                }
            }
            for(int i = 1 ; i <= m ; i++) {
                if(!vis[i]) {
                    Union(T[i].x , T[i].y);
                }
            }
            int cnt = 0;
            for(int i = q ; i >= 1 ; i--) {
                if(node[i].z == 1) {
                    int g = node[i].x;
                    int end = find(g);
                    if(num[end] > val[g])
                        ans[cnt++] = pos[end];
                    else
                        ans[cnt++] = -1;
                }
                else {
                    Union(node[i].x , node[i].y);
                }
            }
            for(int i = cnt - 1 ; i >= 0 ; i--) {
                printf("%d
    " , ans[i]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    数组去重
    css盒模型
    px、em、rem的区别
    Html5新标签
    弹性布局
    相对定位与绝对定位
    Hadoop综合大作业
    分布式文件系统HDFS 练习
    安装Hadoop
    爬虫综合大作业
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6596684.html
Copyright © 2011-2022 走看看