中国大学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成果: