zoukankan      html  css  js  c++  java
  • 中国大学MOOC数据结构基础习题集、042、File Transfer

    题目链接:http://www.patest.cn/contests/mooc-ds/04-2

    题目分析:这是一道考察“并查集”的问题,通过的人像2-1一样那么少。

      首先输入的是一个整型数,代表网络中有多少个结点。

      然后输入若干行,每行由1个字符,两个整数组成,字符为I代表增加连接,字符为C代表检查是否连接,字符为S代表结束输入。

      每个字符为C检查连接的时候,要输出yes或者no说明是否连通。

      最后要输出整个网络的情况,如果全部连通则输出The network is connected.,否则输出有多少个连通分量。

    特别说明:这道题比较坑爹,需要有几个点特别注意一下:

      1) 如果你用老师给的Find函数,那你就废废了,那个函数的时间复杂度绝对不能让你AC。不仅吐槽一下。必须要自己写一个,很简单,代码如下:

    int Find( ElementType X )
    {
        if(S[X]==X)
            return X;
        return S[X]=Find(S[X]);
    }

      2) 不需要像课上讲的一样,定义一个结构体,一个是数据区,一个是父结点区,只用一个一维数组就够了!为了方便,我们定义数组的长度比正常的大1,这样方便我们从1开始查起。  

    // 全局变量定义
    int *S;
    // 在main函数中动态申请
    S = new int[num+1];

      3) Union的时候不需要考虑哪个子树大,哪个子树小,并不影响你AC。但是如果考虑的话更好,到底能提高多少速度自己实践下就知道了。

     1 void Union( ElementType X1, ElementType X2)
     2 {
     3     int Root1, Root2;
     4     Root1 = Find(X1);
     5     Root2 = Find(X2);
     6     if ( Root1 != Root2 )
     7     {
     8         if(S[Root1] < S[Root2])
     9         {
    10             S[Root2] = Root1;
    11         }
    12         else
    13         {
    14             S[Root1] = Root2;
    15         }
    16     }
    17 }

    代码分析:

    头文件及全局变量声明:1~5行。这里我们用ElementType代替int,是因为从老师那里拷的算法,用的就是ElementType,各位编写的时候无视就可以了。

    Find函数和Union函数:6~30行。上面已经详细说过了,各位看看就好。

    主函数输入及输出:31~65行。虽然看起来比较多,但是还是很简单的。

     1 #include <iostream>
     2 #define ElementType int
     3 using namespace std;
     4 
     5 int *S;
     6 int Find( ElementType X )
     7 {
     8     if(S[X]==X)
     9         return X;
    10     return S[X]=Find(S[X]);
    11 }
    12 
    13 void Union( ElementType X1, ElementType X2)
    14 {
    15     int Root1, Root2;
    16     Root1 = Find(X1);
    17     Root2 = Find(X2);
    18     if ( Root1 != Root2 )
    19     {
    20         if(S[Root1] < S[Root2])
    21         {
    22             S[Root2] = Root1;
    23         }
    24         else
    25         {
    26             S[Root1] = Root2;
    27         }
    28     }
    29 }
    30 
    31 int main()
    32 {
    33     int num;
    34     cin >> num;
    35     char choose;
    36     int c1, c2;
    37     S = new int[num+1];
    38     for(int i=0; i<=num; i++)   // 初始化
    39         S[i] = i;
    40     while(1)
    41     {
    42         cin >> choose;
    43         if(choose == 'S')
    44             break;
    45         cin >> c1 >> c2;
    46         if(choose == 'I')
    47             Union(c1, c2);
    48         if(choose == 'C')
    49         {
    50             if(Find(c1) == Find(c2))
    51                 cout << "yes" << endl;
    52             else
    53                 cout << "no" << endl;
    54         }
    55     }
    56     int icount=0;
    57     for(int i=1; i<=num; i++)
    58         if(S[i] == i)   // 如果Parent就它自己,证明是根结点
    59             icount++;
    60     if(icount == 1)
    61         cout << "The network is connected." << endl;
    62     else
    63         cout << "There are " << icount << " components." << endl;
    64     return 0;
    65 }

    AC成果:

  • 相关阅读:
    python 按行读取判断是否为空
    python获取目录下所有文件
    Kolakoski
    最小背包问题
    python 求第k个最大数
    python 求最大子序列
    爬取数据的程序
    文件对比程序
    trsd_extract_EDSD_new
    tred_extract_EDED_new
  • 原文地址:https://www.cnblogs.com/clevercong/p/4192953.html
Copyright © 2011-2022 走看看