并查集-检查网络
【问题描述】
给定一个计算机网络以及机器间的双向连线列表,每一条连线允许两端的计算机进行直接的文件传输,其他计算机间若存在一条连通路径,也可以进行间接的文件传输。请写出程序判断:任意指定两台计算机,它们之间是否可以进行文件传输?
【输入要求】
输入若干测试数据组成。对于每一组测试,第1行包含一个整数N(≤10000),即网络中计算机的总台数,因而每台计算机可用1到N之间的一个正整数表示。接下来的几行输入格式为I C1 C2或者 C或者C C1C2或者S,其中C1和C2是两台计算机的序号,I表示在C1和C2间输入一条连线,C表示检查C1和C2间是否可以传输文件,S表示该组测试结束。当N为0时,表示全部测试结束,不要对该数据做任何处理。
【输出要求】
对每一组C开头的测试,检查C1和C2间是否可以传输文件,若可以,则在一行中输出“yes”,否则输出“no”。当读到S时,检查整个网络。若网络中任意两机器间都可以传输文件,则在一行中输出“The network is connected.”,否则输出“There are k components.”,其中k是网络中连通集的个数。两组测试数据之间请输出一空行分隔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | #include <iostream> using namespace std; #define MAX_N 10001 int par[MAX_N]; // 父亲 int rank[MAX_N]; // 树的高度 // 初始化n个元素 void init( int n) { for ( int i = 1; i <= n; ++ i) { par[i] = i; rank[i] = 0; } } // 查询树的根 int find( int x) { if (par[x] == x) return x; else return par[x] = find(par[x]); } // 合并x和y所属的集合 void unite( int x, int y) { x = find(x); y = find(y); if (x == y) return ; if (rank[x] > rank[y]) { par[y] = x; } else { par[x] = y; if (rank[x] == rank[y]) { rank[x] ++; } } } // 判断x和y是否属于同一个集合 bool same( int x, int y) { return find(x) == find(y); } int main() { // num 为机器总数, m1, m2 为任意两台机器 int num, m1, m2; // command为指令 char command; cout << "请输入机器总数:" << endl; while (cin >> num) { // 当N为0时,表示全部测试结束,不要对该数据做任何处理。 if (num == 0) break ; if (num < 1 || num > MAX_N) { cout << "数据越界, 请重新输入" << endl; continue ; } // 并查集开始 init(num); cout << "请输入指令:" << endl; while (cin >> command) { // 错误指令的处理 if (command != 'S' && command != 'C' && command != 'I' ) { cout << "指令错误, 请重新输入" << endl; continue ; } // 当读到S时,检查整个网络。 // 若网络中任意两机器间都可以传输文件,则在一行中输出"The network is connected." // 否则输出"There are k components." if (command == 'S' ) { int count = 0; for ( int i = 1; i <= num; ++ i) { if (par[i] == i) count ++; } if (count == 1) { cout << "The network is connected." << endl; } else { cout << "There are " << count << " components." << endl; } cout << endl; cout << "请输入机器总数:" << endl; break ; } // 输入两个机器 // cout << "请输入两个机器编号:" << endl; cin >> m1 >> m2; // C开头的测试,检查C1和C2间是否可以传输文件 // 若可以,则在一行中输出"yes",否则输出"no"。 if (command == 'C' ) { if (same(m1, m2)) { cout << "yes" << endl; } else { cout << "no" << endl; } cout << "请输入指令:" << endl; } // I表示在C1和C2间输入一条连线 if (command == 'I' ) { unite(m1, m2); cout << "请输入指令:" << endl; } } } return 0; } /* 请输入机器总数: 3 请输入指令: I 3 1 请输入指令: I 2 3 请输入指令: C 1 2 yes 请输入指令: S The network is connected. 请输入机器总数: 3 请输入指令: C 1 2 no 请输入指令: I 1 2 请输入指令: C 1 2 yes 请输入指令: S There are 2 components. */ |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步