中国大学MOOC-数据结构基础习题集、04-2、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成果:

 

posted @ 2014-12-30 10:07  聪明的聪聪  阅读(884)  评论(11编辑  收藏  举报