码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 3261 Connections in Galaxy War

时间:2015-02-01 20:23:46      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

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

 

题意:

一. 给定N个星球(0,...,N-1)及其对应的power(p0,...pn-1)

二. 给定M条星球a与b间(a!=b)的通路

三. 给出Q个指令,"destroy a b"代表此时星球a b间的通路(必定已连接)被破坏了,"query a"要求输出当时应对星球a进行救援的星球的编号

规则为: ①与星球a有直接或间接通路的星球中power最大的

②该星球的power大于pa

③符合①②的星球中取编号最小的

④如无符合的星球,则输出"-1"

ps: 含多个case,case之间需输出空行

 

思路:

离线处理+并查集

逆向处理,一次性读入并保存所有指令,用map标记被破坏的边,将未被破坏的边用并查集连接,生成最终的状态

再从后往前处理指令,是destroy就并查集连接该边,是query就判断自身是否为根来决定答案

将答案依次保存进数组中,最后逆向输出

 

代码: 190ms 2264KB

#include <cstdio>
#include <map>
using namespace std;

#define N 10001
#define NN 50001
#define swap(x,y) x=x^y;y=x^y;x=x^y;

struct Node {
    int a, b;
    bool m;  //两种指令
} edge[N << 1], que[NN];  //边,指令
int fa[N], pw[N], ans[NN];  //父节点,power值,答案
map<int, bool> mp;  //标记被破坏的边

void init(int n) {
    mp.clear();
    for (int i = 0; i < n; i++) {
        fa[i] = i;
    }
}

int findfa(int n) {
    return n == fa[n] ? n : fa[n] = findfa(fa[n]);
}

void unite(int a, int b) {
    a = findfa(a);
    b = findfa(b);
    if (a != b) {
        if (pw[a] > pw[b] || pw[a] == pw[b] && a < b) {  //power大及编号小的为父节点
            fa[b] = a;
        }
        else {
            fa[a] = b;
        }
    }
}

int main() {
    int n, m, q;
    char c[8];
    bool f = 1;
    while (~scanf("%d", &n)) {
        if (!f) {
            printf("\n");
        }
        f = 0;
        init(n);
        for (int i = 0; i < n; i++) {
            scanf("%d", &pw[i]);
        }
        scanf("%d", &m);
        for (int i = 0; i < m; i++) {
            scanf("%d%d" , &edge[i].a , &edge[i].b);
            if (edge[i].a > edge[i].b) {
                swap(edge[i].a , edge[i].b);  //小号在前
            }
        }
        scanf("%d", &q);
        for (int i = 0; i < q; i++) {
            scanf("%s", c);
            if (c[0] == d) {
                scanf("%d%d", &que[i].a, &que[i].b);
                if (que[i].a > que[i].b) {
                    swap(que[i].a , que[i].b);  //小号在前
                }
                que[i].m = 1;
                mp[que[i].a * N + que[i].b] = 1;  //被毁标记
            }
            else {
                scanf("%d", &que[i].a);
                que[i].m = 0;
            }
        }
        for (int i = 0; i < m; i++) {
            if (!mp[edge[i].a * N + edge[i].b]) {  //未被毁则合并
                unite(edge[i].a, edge[i].b);
            }
        }
        int ansn = 0;
        for (int i = q - 1; i >= 0; i--) {
            if (que[i].m) {
                unite(que[i].a, que[i].b);  //被毁的连回去
            }
            else {
                int t = findfa(que[i].a);
                if (pw[t] <= pw[que[i].a]) {  //根的power不比自己大
                    ans[ansn++] = -1;
                }
                else {
                    ans[ansn++] = t;
                }
            }
        }
        for (int i = ansn - 1; i >= 0; i--) {
            printf("%d\n", ans[i]);
        }
    }
    return 0;
}

 

ZOJ 3261 Connections in Galaxy War

标签:

原文地址:http://www.cnblogs.com/rsola/p/4266007.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!