題目鏈接: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成果: