ZOJ-3261 Connections in Galaxy War---离线操作+逆序并查集
题目链接:
https://cn.vjudge.net/problem/ZOJ-3261
题目大意:
给你一些点,还有一些边,每个点上都有一个权值,然后有一些询问,分为两种,
query a 询问与a直接或者间接想连的点中最大权值的是那个点,输出那个点,如果那个点的权值小于等于a的权值,那么就输出-1,还有另一种操作就是destroy a b意思是删除a b的关系。
解题思路:
此处需要删边,应该想到逆序离线处理。先将所有需要删除的边直接删除,将所有操作存下来逆序处理,对于需要删的边就变成添加这条边。求与a相连的权值最大的点,就直接求a这个连通块中的最大权值的点,可以用并查集求,添加边的时候就合并两个连通块即可。
注意合并连通块时,权值大的为父亲,如果权值相同,那么编号小的为父亲
在最后判断是否存在为-1的时候,需要用连通块根节点的权值和当前询问节点权值进行比较,不可用下标相等比较
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
int n, m;
int a[maxn];//每个点的权值
vector<int>Map[maxn];//存边(只保留编号小的指向编号大的边)
struct node//存储操作
{
int type, x, y;
}op[maxn];
vector<int>ans;
int fa[maxn];
int Find(int x)
{
return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
void Union(int x, int y)
{
x = Find(x), y = Find(y);
if(a[x] < a[y])
{
fa[x] = y;
}
else if(a[x] > a[y])
{
fa[y] = x;
}
else if(x != y)
{
if(x < y)
{
fa[y] = x;
}
else
{
fa[x] = y;
}
}
}
int main()
{
int flag = ;
while(scanf("%d", &n) != EOF)
{
if(flag++)printf("\n");
memset(op, , sizeof(op));
memset(a, , sizeof(a));
ans.clear();
for(int i = ; i < n; i++)scanf("%d", &a[i]), Map[i].clear(), fa[i] = i; scanf("%d", &m);
int u, v;
while(m--)
{
scanf("%d%d", &u, &v);
if(u > v)swap(u, v);
Map[u].push_back(v);
}
scanf("%d", &m);
char s[];
for(int i = ; i <= m; i++)
{
scanf("%s", s);
if(s[] == 'q')
op[i].type = , scanf("%d", &op[i].x);
else //先将边全部删除,逆序操作,逐渐增加边
{
op[i].type = ;
scanf("%d%d", &u, &v);
if(u > v)swap(u, v);
op[i].x = u, op[i].y = v;
Map[u].erase(find(Map[u].begin(), Map[u].end(), v));
}
}
for(int i = ; i < n; i++)
{
for(int j = ; j < Map[i].size(); j++)
{
Union(i, Map[i][j]);
}
}
for(int i = m; i >= ; i--)
{
if(op[i].type == )
{
u = Find(op[i].x);
if(a[u] <= a[op[i].x])u = -;
//不能仅仅判断u != op[i].x 因为根节点可能为其他点并且权值等于该节点权值,此时该节点也应该认为无连接
ans.push_back(u);
}
else
{
Union(op[i].x, op[i].y);
}
}
for(int i = ans.size() - ; i >= ; i--)
printf("%d\n", ans[i]);
}
return ;
}
ZOJ-3261 Connections in Galaxy War---离线操作+逆序并查集的更多相关文章
- ZOJ 3261 Connections in Galaxy War (逆向+带权并查集)
题意:有N个星球,每个星球有自己的武力值.星球之间有M条无向边,连通的两个点可以相互呼叫支援,前提是对方的武力值要大于自己.当武力值最大的伙伴有多个时,选择编号最小的.有Q次操作,destroy为切断 ...
- 洛谷 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
点击打开链接zoj 3261 思路: 带权并查集 分析: 1 题目说的是有n个星球0~n-1,每个星球都有一个战斗值.n个星球之间有一些联系,并且n个星球之间会有互相伤害 2 根本没有思路的题,看了网 ...
- 题解报告: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 题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现 ...
- Connections in Galaxy War ZOJ - 3261 离线操作+逆序并查集 并查集删边
#include<iostream> #include<cstring> #include<stdio.h> #include<map> #includ ...
- 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(并查集删边)
https://cn.vjudge.net/problem/ZOJ-3261 题意 银河系各大星球之间有不同的能量值, 并且他们之间互相有通道连接起来,可以用来传递信息,这样一旦有星球被怪兽攻击,便可 ...
随机推荐
- 数据库命令行操作语句 linux 详细
1.连接数据库 命令: use <数据库名> 2.查看表的引擎类型等状态信息 SHOW TABLE STATUS [FROMdb_name] [LIKE 'pattern'] 3.当前数据 ...
- Spring 学习(五)--- 事务(未完成)
问题 : Spring 事务传播机制是怎么样的,在什么应用场景使用 事务是什么 我们使用的框架可能是Hibernate/JPA或者是Mybatis,都知道的底层是需要一个session/connect ...
- 手把手教你用 Keras 实现 LSTM 预测英语单词发音
1. 动机 我近期在研究一个 NLP 项目,根据项目的要求,需要能够通过设计算法和模型处理单词的音节 (Syllables),并对那些没有在词典中出现的单词找到其在词典中对应的押韵词(注:这类单词类似 ...
- 题解 P1068 【分数线划定】
由于涉及到排序和对应序号 那就定义一个结构体 结合STL模板中的sort日常沉迷sort 提示:虽然我也是蒟弱 sort是快速排序函数,有两个或三个参数, 两个参数适用于平常的数字类型,即形sort( ...
- Java学习--Jsp简介
- 三:SpringCloud-Ribbon
六:Ribbon负载均衡 1. 概述 1.1 是什么 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套==客户端 负载均衡==的工具. 简单的说,Ribbon是Net ...
- 十二、curator recipes之双重屏障DoubleBarrier
简介 curator实现了单个屏障barrier和双重屏障DoubleBarrier,单个屏障就是在一个进程里面设置了屏障,并等待其它进程去移除这个屏障,否则一直阻塞.双重屏障就是设置了两道屏障,两个 ...
- golang rpc 简单范例
RPC(Remote Procedure Call Protocol)--远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. 它的工作流程如下图: go ...
- SQL修改表结构
--(1)向数据库Student表中添加Name字段 use MR_NXT alter table student add Name char(20) --(2)将Student表中Name的字段的数 ...
- git杂记-记录每次更新到仓库
git status 和 git diff的运用 git status 记录的是关于仓库文件是否有变更,例如是否被修改,是否被添加到暂村区.至于文件更改了什么内容该命令并不关心: git status ...