zoukankan      html  css  js  c++  java
  • 并查集

    并查集初步

    Disjoint Sets

     

    例1 亲戚

    AYYZOJ p1598

    COGS p259

    若某个家族人员过于庞大,要判断两个人是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。
    规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。
    数据输入
    第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关系。
    以下m行:每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Ai和Bi具有亲戚关系。
    接下来p行:每行两个数Pi,Pj,询问Pi和Pj是否具有亲戚关系。
    数据输出
    P行,每行一个’Yes’或’No’。表示第i个询问的答案为“具有”或“不具有”亲戚关系。
    样例
    input.txt
    6 5 3
    1 2
    1 5
    3 4
    5 2
    1 3
    1 4
    2 3
    5 6
    output.txt
    Yes
    Yes
    No
    分析这个题目是最基础的并查集问题,运用基本的并查集工具就可以解决了。
     1 Var
     2   fa: array[0..5000] Of integer;
     3   i,k,n,m,p,k1,k2: integer;
     4 Function getfa(x:integer): integer;
     5 Begin
     6   If fa[x]=0 Then getfa := x
     7   Else
     8     Begin
     9       fa[x] := getfa(fa[x]);
    10       getfa := fa[x]
    11     End;
    12 End;
    13 Procedure union(x,y:integer);
    14 Var i,j: integer;
    15 Begin
    16   i := getfa(x);
    17   j := getfa(y);
    18   If i<>j Then fa[i] := j;
    19 End;
    20 Begin
    21   readln(n,m,p);
    22   fillchar(fa,sizeof(fa),0);
    23   For i:=1 To m Do
    24     Begin
    25       readln(k1,k2);
    26       union(k1,k2);
    27     End;
    28   For i:=1 To p Do
    29     Begin
    30       readln(k1,k2);
    31       If getfa(k1)<>getfa(k2) Then writeln('No')
    32       Else  writeln('Yes');
    33     End;
    34 End.

     几个用到并查集的地方:

    1.
    判断是否有亲戚关系。

    2.
    两个物品放在一起会爆炸,爆炸有传递性(A和B爆,B和C爆,A和C爆);
    判断哪些物品放在一起会爆。

    3.
    连通块

    需要注意的是,每个集合可以存很多信息,比如当前集合的最大值,顶点数量等等。

    推荐阅读:并查集详解

  • 相关阅读:
    Android WebView使用
    Android
    Instant Buy Android API Tutorial
    cocos2dx 手势识别
    cocos2d-x 判断两条直线是否相交
    golang 环境bash 以及shell
    技术描述
    golang web开发获取get、post、cookie参数
    Linux curl 模拟form表单提交信息和文件
    Golang HTTP文件上传
  • 原文地址:https://www.cnblogs.com/vacation/p/5189428.html
Copyright © 2011-2022 走看看