中國大學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成果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM