pta 编程题13 File Transfer
其它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 }