zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    ACM的算法分类 2015-04-16 14:25 22人阅读 评论(0) 收藏
    初学Larevel 2014-08-21 11:24 90人阅读 评论(0) 收藏
    初学PHP&MySQL 2014-05-31 12:40 92人阅读 评论(0) 收藏
    codeforces 570 E. Pig and Palindromes (dp)
    codeforces 570 D. Tree Requests (dfs序)
    poj 2157 Maze (bfs)
    cf 570 C. Replacement (暴力)
    cf 570B B. Simple Game(构造)
    cf 570 A. Elections
    hdu 1429胜利大逃亡(续) (bfs+状态压缩)
  • 原文地址:https://www.cnblogs.com/kirai/p/7026465.html
Copyright © 2011-2022 走看看