ZOJ-3261 Connections in Galaxy War 并查集 离线操作
题目链接:https://cn.vjudge.net/problem/ZOJ-3261
题意
有n个星星,之间有m条边
现一边询问与x星连通的最大星的编号,一边拆开一些边
思路
一开始是真不会,甚至想用dfs模拟
最后查了一下,这个题原来是要离线操作,拆边就变为合并
这很为难哈哈,本以为有个什么更好的数据结构(动态树?)
存边我们用一个set<int>来存一个数字即可(bfs这类写多了就很容易考虑到压缩数据)
还有一个重要的点,就是并查集的join可以用来维护一个最大(小)数据作为跟节点的值
代码
#include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=10000, maxq=50000;
struct IdxMap{
int val, idx;
IdxMap(int val=0, int idx=0):
val(val), idx(idx) {}
bool operator < (const IdxMap &a) const{
if (val!=a.val) return val>a.val;
return idx<a.idx;
}
}imap[maxn+5];
struct Operate{
// true for destory(add)
bool ifadd; int a, b;
Operate(bool ifadd=false, int a=-1, int b=-1):
ifadd(ifadd), a(a), b(b) {}
}operate[maxq+5];
struct Node{
int pre, data;// rank, data;
Node(int pre=0, int data=0):// int rank=0, int data=0):
pre(pre), data(data) {}// rank(rank), data(data) {}
}node[maxn+5];
int n, m, q, asize=0, ans[maxq+5];
set<int> edge; // smeller proir
int find(int x){
return (node[x].pre==x)?x:(node[x].pre=find(node[x].pre));
}
void join(int a, int b){
a=find(a); b=find(b);
if (a==b) return;
// if (node[a].rank==node[b].rank) node[a].rank++;
if (node[a].data>=node[b].data) node[b].pre=a;
else node[a].pre=b;
}
inline int getcode(const int &a, const int &b){
if (a<b) return a*maxn+b;
return b*maxn+a;
}
int findBiggest(int x){
// int &val=node[x].data;
// for (int i=0; i<n; i++){
// if (val>=imap[i].val) return -1;
// if (find(x)==find(imap[i].idx)) return imap[i].idx;
// }return -1;
int root=find(x);
if (node[root].data>node[x].data) return root;
return -1;
}
int main(void){
int first=true;
while(scanf("%d", &n)==1 && n){
edge.clear();
asize=0;
for (int i=0, tmp; i<n; i++){
scanf("%d", &tmp);
imap[i]=IdxMap(tmp, i);
node[i]=Node(i, tmp);
}sort(imap, imap+n);
scanf("%d", &m);
for (int i=0, a, b; i<m; i++){
scanf("%d%d", &a, &b);
edge.insert(getcode(a, b));
}
char str[25];
scanf("%d", &q);
for (int i=0, a, b; i<q; i++){
scanf("%s", str);
if (str[0]=='d'){
scanf("%d%d", &a, &b);
operate[i]=Operate(true, a, b);
edge.erase(getcode(a, b));
}else if (str[0]=='q'){
scanf("%d", &a);
operate[i]=Operate(false, a, -1);
}
}
for (set<int>::iterator it=edge.begin(); it!=edge.end(); it++)
join((*it)/maxn, (*it)%maxn);
for (int i=q-1; i>=0; i--){
if (operate[i].ifadd) join(operate[i].a, operate[i].b);
else ans[asize++]=findBiggest(operate[i].a);
}
if (!first) printf("\n");
else first=false;
for (int i=asize-1; i>=0; i--) printf("%d\n", ans[i]);
}
return 0;
}
| Time | Memory | Length | Lang | Submitted |
|---|---|---|---|---|
| 260ms | 2124kB | 2764 | C++ (g++ 4.7.2) | 2018-03-20 23:26:36 |
> 18-03-21 Update:并查集维护最值
ZOJ-3261 Connections in Galaxy War 并查集 离线操作的更多相关文章
- 洛谷 P1197 BZOJ 1015 [JSOI2008]星球大战 (ZOJ 3261 Connections in Galaxy War)
这两道题长得差不多,都有分裂集合的操作,都是先将所有操作离线,然后从最后一步开始倒着模拟,这样一来,分裂就变成合并,也就是从打击以后最终的零散状态,一步步合并,回到最开始所有星球都被连为一个整体的状态 ...
- ZOJ 3261 - Connections in Galaxy War ,并查集删边
In order to strengthen the defense ability, many stars in galaxy allied together and built many bidi ...
- 题解报告:zoj 3261 Connections in Galaxy War(离线并查集)
Description In order to strengthen the defense ability, many stars in galaxy allied together and bui ...
- zoj 3261 Connections in Galaxy War(并查集逆向加边)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261 题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现 ...
- ZOJ 3261 Connections in Galaxy War(逆向并查集)
参考链接: http://www.cppblog.com/yuan1028/archive/2011/02/13/139990.html http://blog.csdn.net/roney_win/ ...
- ZOJ 3261 Connections in Galaxy War (逆向+带权并查集)
题意:有N个星球,每个星球有自己的武力值.星球之间有M条无向边,连通的两个点可以相互呼叫支援,前提是对方的武力值要大于自己.当武力值最大的伙伴有多个时,选择编号最小的.有Q次操作,destroy为切断 ...
- zoj 3261 Connections in Galaxy War
点击打开链接zoj 3261 思路: 带权并查集 分析: 1 题目说的是有n个星球0~n-1,每个星球都有一个战斗值.n个星球之间有一些联系,并且n个星球之间会有互相伤害 2 根本没有思路的题,看了网 ...
- ZOJ - 3261 Connections in Galaxy War(并查集删边)
https://cn.vjudge.net/problem/ZOJ-3261 题意 银河系各大星球之间有不同的能量值, 并且他们之间互相有通道连接起来,可以用来传递信息,这样一旦有星球被怪兽攻击,便可 ...
- ZOJ3261 Connections in Galaxy War 并查集
分析:对于这种删边操作,我们通常可以先读进来,然后转化离线进行倒着加边 #include <stdio.h> #include <string.h> #include < ...
随机推荐
- JavaScript实现记住密码功能
用js实现记住密码功能,但是前端记住密码不安全,最好还是不要用.我感觉这个记住密码应该是通过与后台建立一个会话来实现. 这个效果的测试地址在:http://ofoyou.com/blog/rePass ...
- 线程进阶:多任务处理(17)——Java中的锁(Unsafe基础)
在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...
- js邮箱,汉字,数字 表单验证
//电子邮箱验证 function isEmail(str) { var myreg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_ ...
- 小程序canvas生成二维码图片踩的坑
1:生成临时图片,保证画布被加载以及渲染(即本身不可以 hidden 或是 上级元素不可以 hidden 或是 wx:if 隐藏等) == > 建议:因为 canvas 的组件层级(z-inde ...
- ansible搭建mysql主主模式
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)等优点,实现了批量系统配置.批量程序部署.批量运行命 ...
- 3步简单实现SSH无密码登录
下面简单的做下实验: 一:准备2台服务器: 192.168.10.101 2 192.168.10.102 二:关键字解释 ssh-keygen : 产生公钥与私钥对 ssh-copy-id :将本 ...
- CentOS上手动配置nginx.services
[Unit] Description=Dynamic web platform based on NGINX and LuaJIT After=network.target remote-fs.tar ...
- 【codeforces 816B】Karen and Coffee
[题目链接]:http://codeforces.com/contest/816/problem/B [题意] 给你很多个区间[l,r]; 1<=l<=r<=2e5 一个数字如果被k ...
- Java基础学习总结(4)——对象转型
一.对象转型介绍 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型.转型的意思是:如把float类型转成int类型,把double类 ...
- 批量修改文件的编码格式至UTF-8
批量修改文件的编码格式至UTF-8 学习了: https://jingyan.baidu.com/article/e8cdb32b47a1ea37042bad11.html http://blog.c ...