Connections in Galaxy War(逆向并查集)

本文介绍了一种使用逆向并查集解决银河战争中星际联络中断问题的方法。在银河战争中,星球间原有的双向隧道遭到破坏,导致求援困难。题目要求在给定的星球信息和隧道连接后,处理连接破坏和查询请求,判断星球能否找到比自己强大的援助者。题目提供输入输出样例,并给出了解题思路,涉及并查集的离散化操作和反向操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

In order to strengthen the defense ability, many stars in galaxy allied together and built many bidirectional tunnels to exchange messages. However, when the Galaxy War began, some tunnels were destroyed by the monsters from another dimension. Then many problems were raised when some of the stars wanted to seek help from the others.

In the galaxy, the stars are numbered from 0 to N-1 and their power was marked by a non-negative integer pi. When the star A wanted to seek help, it would send the message to the star with the largest power which was connected with star A directly or indirectly. In addition, this star should be more powerful than the star A. If there were more than one star which had the same largest power, then the one with the smallest serial number was chosen. And therefore, sometimes star A couldn’t find such star for help.

Given the information of the war and the queries about some particular stars, for each query, please find out whether this star could seek another star for help and which star should be chosen.

Input

There are no more than 20 cases. Process to the end of file.
For each cases, the first line contains an integer N (1 <= N <= 10000), which is the number of stars. The second line contains N integers p0, p1, … , pn-1 (0 <= pi <= 1000000000), representing the power of the i-th star. Then the third line is a single integer M (0 <= M <= 20000), that is the number of tunnels built before the war. Then M lines follows. Each line has two integers a, b (0 <= a, b <= N - 1, a != b), which means star a and star b has a connection tunnel. It’s guaranteed that each connection will only be described once.
In the (M + 2)-th line is an integer Q (0 <= Q <= 50000) which is the number of the information and queries. In the following Q lines, each line will be written in one of next two formats.

“destroy a b” - the connection between star a and star b was destroyed by the monsters. It’s guaranteed that the connection between star a and star b was available before the monsters’ attack.
“query a” - star a wanted to know which star it should turn to for help

There is a blank line between consecutive cases.

Output

For each query in the input, if there is no star that star a can turn to for help, then output “-1”; otherwise, output the serial number of the chosen star.
Print a blank line between consecutive cases.

Sample Input
2
10 20
1
0 1
5
query 0
query 1
destroy 0 1
query 0
query 1

Sample Output
1
-1
-1
-1

当然还是要翻译一下啦♪(^ ∇ ^*)

为了加强防御能力,银河系中的许多恒星联合起来建造了许多双向隧道来交换信息。然而,当银河战争开始时,一些隧道被另一个维度的怪物摧毁。当一些明星想要寻求其他人的帮助时,提出了许多问题。在星系中,恒星的编号从0到N-1,它们的功率用非负整数pi标记。当明星A想寻求帮助时,它会将信息发送给直接或间接与星A相关的最大功率的恒星。此外,这颗恒星应该比恒星A更强大。如果有不止一颗恒星具有相同的最大功率,那么选择具有最小序列号的恒星。因此,有时候明星A无法找到这样的明星寻求帮助。鉴于战争的信息和对某些特定恒星的询问,对于每个查询,请查明这颗恒星是否可以寻求另一颗恒星寻求帮助以及应该选择哪颗恒星。

输入
不超过20个案例。处理到文件结尾。对于每种情况,第一行包含整数N(1 <= N <= 10000),这是星数。第二行包含N个整数p0,p1,…,pn-1(0 <= pi <= 1000000000),表示第i个星的功率。然后第三行是单个整数M(0 <= M <= 20000),即战争前建立的隧道数。然后是M行。每行有两个整数a,b(0 <= a,b <= N - 1,a!= b),这意味着星a和星b具有连接隧道。保证每个连接只会被描述一次。在第(M + 2)行中是整数Q(0 <= Q <= 50000),它是信息和查询的数量。在以下Q行中,每行将以下两种格式之一写入。“摧毁一个b” - 星星a和星星b之间的联系被怪物摧毁了。保证在怪物的攻击之前,星球a和星星b之间的连接是可用的。“查询一个” - 明星一个想知道哪个星应该求助连续案例之间有一个空行。

输出
对于输入中的每个查询,如果没有星星可以转向寻求帮助,则输出“-1”;否则,输出所选星号的序列号。在连续案例之间打印一个空行。

思路:这道题就是一个并查集的题目,但是我们通常都是连接起来,判断是否为同一父亲,而这道题则是出现了断开的操作,这个时候我们就要考虑离散操作,将所有的操作保存下来,然后逆着进行操作,如果查询,则查询数据,如果为断开连接,这个时候我们就连接起来,(在此之前就不用连接起来,因为是反过来,那么断开之后就没连接起来),这样的话,就只有连接操作了,也就是反向并查集~这道题很不错,可以学习下

代码如下(* ^ ▽ ^ *) (有注释的哦~)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define P pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int mx=1e4+10;
struct nodea{
   
    
	int x;
	int y;
}s[mx*5]
### 并查集算法实现集合问题 以下是基于 JavaScript 的并查集算法代码示例,该代码可以用来解决与集合分组、合并和查询相关的问题: #### 初始化并查集类 ```javascript class UnionFind { constructor(n) { this.parent = Array.from({ length: n }, (_, i) => i); // 初始时每个节点的父节点都是自己 this.rank = Array(n).fill(0); // 用于优化树的高度 } find(x) { // 查找操作:找到 x 所属集合的根节点,并进行路径压缩 if (this.parent[x] !== x) { this.parent[x] = this.find(this.parent[x]); } return this.parent[x]; } union(x, y) { // 合并操作:将两个元素所在的集合合并 let rootX = this.find(x); let rootY = this.find(y); if (rootX === rootY) return; // 如果已经在同一个集合中,则无需处理 if (this.rank[rootX] > this.rank[rootY]) { this.parent[rootY] = rootX; } else if (this.rank[rootX] < this.rank[rootY]) { this.parent[rootX] = rootY; } else { this.parent[rootY] = rootX; this.rank[rootX]++; } } countSets() { // 统计当前有多少个独立的集合 const roots = new Set(); for (let i = 0; i < this.parent.length; i++) { roots.add(this.find(i)); } return roots.size; } } ``` 上述代码实现了并查集的核心功能 `find` 和 `union` 方法。其中 `find` 方法负责查找某个元素所属集合的代表元(即根节点),并通过路径压缩优化性能;而 `union` 方法则负责将两个不同集合中的元素合并成一个集合。 #### 使用场景举例 假设我们需要解决一个问题:给定一组城市之间的连接关系,判断这些城市被划分为多少个连通区域。可以通过如下方式调用上面定义好的 `UnionFind` 类来解决问题[^2]: ```javascript function connectedCities(connections, numCities) { const uf = new UnionFind(numCities); // 将所有相连的城市加入同一集合 connections.forEach(([cityA, cityB]) => { uf.union(cityA - 1, cityB - 1); // 假设城市编号从1开始,因此减去1适配数组索引 }); // 返回最终的集合数量 return uf.countSets(); } // 测试数据 const citiesConnections = [ [1, 2], [2, 3], [4, 5] ]; console.log(connectedCities(citiesConnections, 5)); // 输出应为 2 ``` 此函数接收两参数——城市的连接列表以及总共有几个城市。它会创建一个新的并查集实例并将每一对已知相互连接的城市放入相同的集合里。最后计算剩余的不同集合数目作为结果返回。 ### 总结 通过以上方法能够有效利用并查集这一高效工具快速求解涉及动态变化集合归属情况下的各类复杂度较高的组合型难题[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值