[Swust OJ 856]--Huge Tree(并查集)

并查集与树形数据结构的应用实例
本文探讨了并查集在处理树形结构数据时的应用,具体包括如何通过并查集实现树的合并操作及查询操作,以及解决实际问题的方法。详细介绍了输入输出格式、解题思路和代码实现。

 

题目链接:http://acm.swust.edu.cn/problem/856/

 

Time limit(ms): 1000        Memory limit(kb): 10000

 

Description

  There are N trees in a forest. At first, each tree contains only one node as its root. And each node is marked with a number.

  You're asked to do the following two operations:

  A X Y, you need to link X's root to Y as a direct child. If X and Y have already been in the same tree, ignore this operation.

  B X, you need to output the maximum mark in the chain from X to its root (inclusively).

 

Input

  The first line contains an integer T, indicating the number of followed cases. (1 <= T <= 20)

  For each case, the first line contains two integers N and M, indicating the number of trees at beginning, and the number of operations follows,  respectively. (1 <= N, M <= 100,000)

  And the following line contains N integers, which are the marks of the N trees. (0 <= Mark <= 100,000)

  And the rest lines contain the operations, in format A X Y, or B X, (0 <= X, Y < N).

 

Output

  For each 'B X' operation, output the maximum mark.

 

Sample Input

  
1
5 5
5 4 2 9 1
A 1 2
A 0 4
B 4
A 1 0
B 1
 
Sample Output
 
  

1

5

 
 

题目大意:就是一个数组(下标从零开始),有对应的A,B操作,A a,b,是把a所在集合归并到b上,

              若某一个集合已合并不进行操作,然B a,就是查询a集合中的最大值。

 

解题思路:运用并查集就是,注意a集合到b所在集合,并查集合并区分一下就可以了

代码如下:

 1 #include <stdio.h>
 2 int n, m, maxn, t, f[100005], cur[100005];
 3 
 4 void init(){
 5     scanf("%d%d", &n, &m);
 6     for (int i = 0; i <= n; i++){
 7         scanf("%d", &cur[i]);
 8         f[i] = i;
 9     }
10 }
11 
12 int findset(int x){
13     maxn = cur[x];
14     if (f[x] == x) return x;
15     int y = findset(f[x]);
16     if (maxn > cur[x]) cur[x] = maxn;
17     else maxn = cur[x];
18     return f[x] = y;
19 }
20 
21 void mergy(){
22     int i, x, y;
23     char k[3];
24     for (i = 0; i < m; i++){
25         scanf("%s", k);
26         if (k[0] == 'A'){
27             scanf("%d%d", &x, &y);
28             int a = findset(x), b = findset(y);
29             if (a != b) f[a] = y;//注意和传统并查集的区别
30         }
31         else{
32             scanf("%d", &x);
33             findset(x);
34             printf("%d\n", cur[x]);
35         }
36     }
37 }
38 
39 int main(){
40     scanf("%d", &t);
41     while (t--){
42         init();
43         mergy();
44     }
45     return 0;
46 }
View Code

 

转载于:https://www.cnblogs.com/zyxStar/p/4564518.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值