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

    并查集主要是用来查找图中的节点是否连通。

    思路:若想求两点是否连通,只用判断两点所在的树的根节点是否相同。若相同则连通,否则不连通。

    写法就比如说若编号为1的结点能连到2,2能连到3,那么1和2就都连到3。就是不断降低树的深度。像下图一样

     

    主要代码

     1 int p[1005];  //p[i]表示节点i的根节点
     2 void init()    //初始化
     3 {
     4     for(int i = 0; i < 1005; ++i) p[i] = i;
     5     return;
     6 }
     7 int Find(int x)
     8 {
     9     return x == p[x] ? x : p[x] = Find(p[x]);  //找到该节点的根节点
    10 }
    11 void merge(int a, int b)  //合并
    12 {
    13     int pa = Find(a), pb = Find(b);
    14     if(pa == pb) return;  //若已经连通,则什么都不用做
    15     else p[pa] = pb;    //p[pb] = pa 一样    
    16     return;
    17 }

    应用:

    比如说noip2017day2T1

    题目描述

    现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪 中间有许多 半径相同 的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中, 奶酪的下表面为z = 0,奶酪的上表面为z = h。

    现在,奶酪的下表面有一只小老鼠 Jerry,它知道奶酪中所有空洞的球心所在的坐 标。如果两个空洞相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个空洞,特别 地,如果一个空洞与下表面相切或是相交,Jerry 则可以从奶酪下表面跑进空洞;如果 一个空洞与上表面相切或是相交,Jerry 则可以从空洞跑到奶酪上表面。

    位于奶酪下表面的 Jerry 想知道,在 不破坏奶酪 的情况下,能否利用已有的空洞跑 到奶酪的上表面去?

    空间内两点P1(x1,y1,z1)、P2(x2,y2,z2)的距离公式如下:

    dist(P1,P2)=sqrt{(x1 * x2)^2 + (y1 * y2)^2 + (z1 * z2)^2}

    输入输出格式

    输入格式:

    每个输入文件包含多组数据。

    输入文件的第一行,包含一个正整数 TT,代表该输入文件中所含的数据组数。

    接下来是 TT 组数据,每组数据的格式如下: 第一行包含三个正整数 n,hn,h 和 rr,两个数之间以一个空格分开,分别代表奶酪中空 洞的数量,奶酪的高度和空洞的半径。

    接下来的 nn 行,每行包含三个整数 x,y,zx,y,z,两个数之间以一个空格分开,表示空 洞球心坐标为(x,y,z)(x,y,z)。

    输出格式:

    输出文件包含 TT 行,分别对应 TT 组数据的答案,如果在第 ii 组数据中,Jerry 能从下 表面跑到上表面,则输出Yes,如果不能,则输出No (均不包含引号)。

    输入输出样例

    输入样例

    3 
    2 4 1 
    0 0 1 
    0 0 3 
    2 5 1 
    0 0 1 
    0 0 4 
    2 5 2 
    0 0 2 
    2 0 4
    输出样例
    Yes
    No
    Yes

    代码
     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 typedef long long ll; 
     5 int t;
     6 ll x[1005], y[1005], z[1005];
     7 int p[1005];
     8 void init()
     9 {
    10     for(int i = 0; i < 1005; ++i) p[i] = i;
    11     return;
    12 }
    13 int Find(int x)
    14 {
    15     return x == p[x] ? x : p[x] = Find(p[x]);
    16 }
    17 void merge(int a, int b)
    18 {
    19     int pa = Find(a), pb = Find(b);
    20     if(pa == pb) return;
    21     else p[pa] = pb;
    22     return;
    23 }
    24 int main()
    25 {
    26     scanf("%d", &t);
    27     while(t--)
    28     {
    29         init();
    30         int n;
    31         ll h, r;
    32         scanf("%d%lld%lld", &n, &h, &r);
    33         for(int i = 1; i <= n; ++i)
    34         {
    35             scanf("%lld%lld%lld", &x[i], &y[i], &z[i]);
    36             for(int j = 1; j < i; ++j)
    37             {
    38                 ll dis = (x[i] - x[j]) * (x[i] - x[j]) +  
    39                          (y[i] - y[j]) * (y[i] - y[j]) + 
    40                          (z[i] - z[j]) * (z[i] - z[j]);
    41                 if(dis <= 4 * r * r) merge(i, j);
    42             }
    43             if(z[i] <= r) merge(i, 0);      //设下表面是0节点,上表面是n + 1 节点
    44             if(z[i] + r >= h) merge(i, n + 1);
    45         }
    46         
    47         if(Find(0) == Find(n + 1)) printf("Yes\n");  //最后只用判断0节点和 n + 1 节点的根节点是否相同就行
    48         else printf("No\n");
    49     }
    50     return 0;
    51 }

     

  • 相关阅读:
    myeclipse中代码不显示SVN版本号
    java HttpURLConnection 登录网站 完整代码
    新浪微博自动(模拟)登陆详解及实现
    java模拟Cookies登陆
    paper 53 :深度学习(转载)
    paper 52 :windows7环境下theano安装
    paper 51:图像复原
    paper 50 :人脸识别简史与近期进展
    paper 49:论文退稿?审稿人帮你总结了22个能避免的常见问题
    paper 48: Latex中如何制作参考文献
  • 原文地址:https://www.cnblogs.com/mrclr/p/8150723.html
Copyright © 2011-2022 走看看