zoukankan      html  css  js  c++  java
  • 长春理工大学第十四届程序设计竞赛A Rubbish——并查集&&联通块

    题目

    链接

    题意:在 $10^5 imes 10^5$ 的大网格上,给出 $n$ 的格点的坐标,求联通块数(上下左右及对角线都认为相邻)

    分析

    DFS需要遍历网格的每个格点,可能会超时?

    初始化时,对每个格点建立并查集,遍历每个格点将相邻的合并,最终的集合个数就是联通块的个数。

    具体实现时,对 $n$ 个点的坐标排序,因此合并时只需考虑左上部分。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 
     5 const int maxn = 1000000 + 10;
     6 int fa[maxn];  //fa父节点
     7 int mar[maxn];      //记录第i列被覆盖的最大行数对应的下标
     8 pair<int, int>p[maxn];
     9 
    10 //初始化n个节点
    11 void init(int n)
    12 {
    13     for (int i = 1; i <= n; i++)
    14         fa[i] = i;
    15 }
    16 
    17 //查询树的根
    18 int find(int x)
    19 {
    20     if (x != fa[x])
    21         return fa[x] = find(fa[x]);
    22     return fa[x];
    23 }
    24 
    25 //合并x和y所属的集合
    26 void unite(int x, int y)
    27 {
    28     int rx = find(x);
    29     int ry = find(y);
    30     if (x == y)  return;
    31 
    32     fa[rx] = ry;
    33 }
    34 
    35 
    36 int main()
    37 {
    38     int n;
    39     scanf("%d", &n);
    40     for(int i = 1;i <= n;i++)  scanf("%d%d", &p[i].first, &p[i].second);
    41     sort(p+1, p+n+1);   //默认就是按第一维排序
    42     init(n);
    43     for(int i = 1;i <= n;i++)  mar[i] = -1;   //初始化每列都没有元素
    44 
    45     for(int i = 1;i <= n;i++)
    46     {
    47         int x = p[i].first, y = p[i].second;
    48         if(p[i-1].first == x && p[i-1].second == y-1)  unite(i-1, i);  //左边
    49 
    50         if(mar[y-1] != -1 && p[mar[y-1]].first == x-1)  unite(mar[y-1], i);  //左上角
    51 
    52         if(mar[y] != -1 && p[mar[y]].first == x-1)  unite(mar[y], i);  //上方
    53 
    54         if(mar[y+1] != -1 && p[mar[y+1]].first == x-1)  unite(mar[y+1], i);    //右上角
    55         mar[y] = i;
    56     }
    57 
    58     int ans = 0;
    59     for(int i = 1;i <= n;i++)
    60         if(find(i) == i)  ans++;
    61     printf("%d
    ", ans);
    62 
    63     return 0;
    64 }

    参考链接:https://zhuanlan.zhihu.com/p/72702597

  • 相关阅读:
    日期类的时间从为什么是从1970年1月1日(格林威治时间)
    网站缓存技术总结( ehcache、memcache、redis对比)
    干货|java缓存技术详解
    TCP和UDP的区别(转)
    form表单转换为Json字符串数据
    JSON.parse 和 JSON.stringify
    Navicat连接Oracle的几个问题及解决方案
    Python IO编程
    python阶段总结一
    使用git进行版本控制
  • 原文地址:https://www.cnblogs.com/lfri/p/11202229.html
Copyright © 2011-2022 走看看