1. 程式人生 > >pta 編程題13 File Transfer

pta 編程題13 File Transfer

cas union 數據 clu printf www 元素 network size

其它pta數據結構編程題請參見:pta

這道題考察的是union-find並查集。

開始把數組中每個元素初始化為-1,代表沒有父節點。為了使樹更加平衡,可以讓每一個連通分量的樹根的負值代表這個連通分量包含的節點數,然後在union時把小的樹並到大的樹上。

另外在find操作時可以用遞歸的方式使查找路徑上的所有節點的父節點都改為根節點,以實現路徑壓縮,在後續查找過程中會更快。

 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4 
 5 vector<int> computers;
6 7 void _union(int a, int b); 8 int find(int a); 9 void components(); 10 11 int main() 12 { 13 int n, c1, c2; 14 char c; 15 cin >> n; 16 computers.resize(n + 1, -1); 17 do{ 18 cin >> c; 19 switch (c) 20 { 21 case I: 22 cin >> c1 >> c2;
23 _union(c1, c2); 24 break; 25 case C: 26 cin >> c1 >> c2; 27 if (find(c1) == find(c2)) 28 cout << "yes" << endl; 29 else 30 cout << "no" << endl; 31 break
; 32 case S: 33 components(); 34 break; 35 } 36 } while (c != S); 37 return 0; 38 } 39 40 void _union(int a, int b) 41 { 42 int root1 = find(a); 43 int root2 = find(b); 44 if (computers[root1] < computers[root2]) 45 { 46 computers[root1] += computers[root2];//順序不能... 47 computers[root2] = root1;//顛倒! 48 } 49 else { 50 computers[root2] += computers[root1]; 51 computers[root1] = root2; 52 } 53 } 54 /* 55 int find(int a) 56 { 57 for (; computers[a] > 0; a = computers[a]); 58 return a; 59 } 60 */ 61 int find(int a) //帶路徑壓縮的查找 62 { 63 if (computers[a] < 0) return a; 64 else return computers[a] = find(computers[a]); 65 } 66 67 void components() 68 { 69 int count = 0; 70 for (int i = 1; i < computers.size(); i++) 71 { 72 if (computers[i] < 0) count++; 73 } 74 if (count > 1) 75 printf("There are %d components.\n", count); 76 else 77 printf("The network is connected.\n"); 78 }

pta 編程題13 File Transfer