• [ZOJ3261]Connections in Galaxy War(离线,带权并查集)


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

    题意:n个星球,起始有m个联通的条件。接下来会有q次查询,2种,一种是摧毁x和y的联通,另外一种是查询与x联通的星球里p大、id最小的星球。

    离线,首先存下初始状态,接着存query,每一次query要修改一下初始状态的联通情况,最后倒着处理query。即每次摧毁变成unite。并查集合并的时候按照p大id小的顺序合并。

    查询的时候直接找根就行了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef struct Query {
     5     char cmd;
     6     int x, y;
     7     Query() {}
     8     Query(char c, int x, int y) : cmd(c), x(x), y(y) {}
     9 }Query;
    10 const int maxn = 10100;
    11 set<int> G[maxn];
    12 vector<Query> ask;
    13 int n, m, q, p[maxn], pre[maxn];
    14 vector<int> ret;
    15 char cmd[5];
    16 inline int find(int x) { return x == pre[x] ? x : pre[x] = find(pre[x]); }
    17 inline void unite(int x, int y) {
    18     x = find(x); y = find(y);
    19     if(x == y) return;
    20     if(p[x] > p[y]) pre[y] = x;
    21     else if(p[x] < p[y]) pre[x] = y;
    22     else pre[max(x, y)] = min(x, y);
    23 }
    24 
    25 signed main() {
    26     // freopen("in", "r", stdin);
    27     int u, v;
    28     int _ = 0;
    29     while(~scanf("%d",&n)) {
    30         if(_) puts("");
    31         _++;
    32         ask.clear(); ret.clear();
    33         for(int i = 0; i < n; i++) pre[i] = i, G[i].clear();
    34         for(int i = 0; i < n; i++) scanf("%d", &p[i]);
    35         scanf("%d",&m);
    36         for(int i = 0; i < m; i++) {
    37             scanf("%d%d",&u,&v);
    38             G[u].insert(v);
    39             G[v].insert(u);
    40         }
    41         scanf("%d",&q);
    42         while(q--) {
    43             scanf("%s", cmd);
    44             if(cmd[0] == 'q') {
    45                 scanf("%d",&u);
    46                 ask.push_back(Query('q',u,-1));
    47             }
    48             else {
    49                 scanf("%d%d",&u,&v);
    50                 ask.push_back(Query('d',u,v));
    51                 if(G[u].find(v) != G[u].end()) G[u].erase(v);
    52                 if(G[v].find(u) != G[v].end()) G[v].erase(u);
    53             }
    54         }
    55         for(int u = 0; u < n; u++) {
    56             for(set<int>::iterator v = G[u].begin(); v !=G[u].end(); v++) {
    57                 unite(u, *v);
    58             }
    59         }
    60         for(int i = ask.size()-1; i >= 0; i--) {
    61             if(ask[i].cmd == 'q') {
    62                 if(p[find(ask[i].x)] <= p[ask[i].x]) ret.push_back(-1);
    63                 else ret.push_back(find(ask[i].x));
    64             }
    65             else unite(ask[i].x, ask[i].y);
    66         }
    67         for(int i = ret.size()-1; i >= 0; i--) printf("%d
    ", ret[i]);
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    一文告诉你,为什么要研究JVM原理
    高并发中使用到的RateLimiter源码解析
    WEB应用服务架构的演变(扫盲)
    网上安全方面的涉及到的方面(详解)
    JDK安装
    JDKJRKSDK的区别
    本地同时安装oracle客户端与服务端的注意事项
    WMS不同货主的货如何管理
    LeetCode 101
    WMS一物一码、唯一码
  • 原文地址:https://www.cnblogs.com/kirai/p/7026465.html
Copyright © 2020-2023  润新知