zoukankan      html  css  js  c++  java
  • [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
    ", 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
  • 相关阅读:
    WEB前端开发工具的初识
    Linux常见问题的处理方法(长期更新)
    eclipse+tomcat开发web项目
    Android适配--百分比的适配
    TCP通信丢包原因总结
    android 实现类似微信缓存和即时更新好友头像
    是否应该开启WebView硬件加速?
    Android通过浏览器打开app页面并且传递值
    设计模式(五)责任链模式
    Android 最新 Support V4 包大拆分有用吗?
  • 原文地址:https://www.cnblogs.com/zyxStar/p/4564518.html
Copyright © 2011-2022 走看看