zoukankan      html  css  js  c++  java
  • 合根植物

    问题描述

      w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
      这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。


      如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
    输入格式
      第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。
      接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)
      接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。


      格子的编号一行一行,从上到下,从左到右编号。
      比如:5 * 4 的小格子,编号:
      1 2 3 4
      5 6 7 8
      9 10 11 12
      13 14 15 16
      17 18 19 20
    样例输入
    5 4
    16
    2 3
    1 5
    5 9
    4 8
    7 8
    9 10
    10 11
    11 12
    10 14
    12 16
    14 18
    17 18
    15 19
    19 20
    9 13
    13 17
    样例输出
    5
    样例说明
      其合根情况参考下图

    Algorithm

     这是一个考察并查集的题目,题目很简单,但是如果数据量很大的话,常规的模拟时空复杂度都会超。
    因此选择一个好的数据结构很关键。这里参照了[挑战程序设计竞赛(第2版)].巫泽俊.


    AC

     1 #include<iostream>
     2 #include<cstring>
     3 
     4 using namespace std;
     5 
     6 const int MAX_N = 1001*1001;
     7 
     8 int par[MAX_N];        // 父亲
     9 int rank[MAX_N];     // 树的高度
    10 
    11 void Init(int n)
    12 {
    13     memset(rank, 0, sizeof(rank));
    14     for(int i=0;i<n;i++)
    15         par[i] = i;
    16  } 
    17 
    18 // 查询树的根 
    19 int find(int x)
    20 {
    21     return (par[x] == x)?x:(par[x] = find(par[x]));
    22 }
    23 
    24 // 合并 x和 y所属的集合 
    25 void unite(int x, int y)
    26 {
    27     x = find(x);
    28     y = find(y);
    29     if(x == y) return;
    30     if(rank[x] == rank[y]){
    31         par[x] = y;
    32     }
    33     else{
    34         par[y] = x;
    35         if(rank[x] == rank[y]) rank[x]++;
    36     }
    37 }
    38 
    39 bool same(int x, int y)
    40 {
    41     return find(x) == find(y);
    42 }
    43 
    44 int main()
    45 {
    46     int m, n, k, x, y;
    47     while(cin>>m>>n)
    48     {    // 居然是从 1 开始的... 
    49         int c = m*n+1, s = 0;
    50         Init(c);
    51         cin>>k;
    52         while(k--)
    53         {
    54             cin>>x>>y;
    55             unite(x, y);
    56         }
    57         // 所以不能有 0 
    58         while(--c && c != 0)
    59         {
    60             if(par[c] == c) s++;
    61         }
    62         cout<<s<<endl;
    63         s = 0;
    64     }
    65     
    66     return 0;
    67 }
    View Code

     2019-02-10

    16:32:52

  • 相关阅读:
    第四周总结&实验报告二
    实验报告 一
    周总结
    期末总结
    第十二周作业
    第十一周作业
    第十周作业
    第九周作业
    第八周作业
    第五周课程总结&试验报告(三)
  • 原文地址:https://www.cnblogs.com/mabeyTang/p/10359463.html
Copyright © 2011-2022 走看看