赞
踩
我们有一个计算机网络和一系列双向连接。这些连接允许从一个计算机向另一个计算机传输文件。是否可能从网络中的任何计算机向任何其他计算机发送文件?
输入规范:
每个输入文件包含一个测试案例。对于每个测试案例,第一行包含N(2≤N≤10^4),网络中计算机的总数。网络中的每台计算机由1和N之间的正整数表示。然后,在接下来的行中,输入以以下格式给出:
I c1 c2
其中I
代表输入c1
和c2
之间的连接;或
C c1 c2
其中C
代表检查是否可能在c1
和c2
之间传输文件;或
S
其中S
代表停止此案例。
输出规范:
对于每个C
案例,在一行中打印单词"yes"或"no",分别表示是否可能在c1
和c2
之间传输文件。在每个案例的末尾,在一行中打印"The network is connected.“,如果任何一对计算机之间存在路径;或"There are k
components.”,其中k
是这个网络中的连通分量的数量。
Sample Input 1:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S
Sample Output 1:
no
no
yes
There are 2 components.
Sample Input 2:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
I 1 3
C 1 5
S
Sample Output 2:
no
no
yes
yes
The network is connected.
①本题怎么存储并查集
由于题目中所给计算机编号是从1到N,因此可以映射到数组下标0到N-1;则可将数组下标作为计算机编号,数组值作为计算机所在集合的根节点
当计算机本身为根节点时,那么数组值就代表集合中元素的规模大小的负数(这里为负数的原因是为了标识它的根节点的身份)
②怎么查找根节点
由于非根节点的数组值均为正,利用此特征则可以循环遍历找到根节点
③怎么合并集合
由于常规的不加限制的合并会导致出现时间复杂度为O(n²)的情况(详解请看视频:小白-FT.3 按秩归并)
因此有两种优化方法:
④需要的注意的点
#include <iostream> #define MAXSIZE 10000 /* 数组下标对应(计算机编号-1) 当数组所存值为正,对应父节点的下标 当数组所存值为负,代表此节点为根节点,以及此集合中的树高 */ int a[MAXSIZE]; void init(int N) { for (int i = 0; i < N; i++) a[i] = -1; } //根据规模来进行合并 此处a[root]值为负 void Union(int root1, int root2) { //规模大的负过来更小 if (a[root1] < a[root2]) { a[root1] += a[root2]; a[root2] = root1; } else { a[root2] += a[root1]; a[root1] = root2; } } //返回根节点索引 //注意:独立节点的根节点就是自身 int findRoot(int X) { for (; a[X] > 0; X = a[X]); return X; } void connect() { int u, v; std::cin >> u >> v; int root1 = findRoot(u - 1); int root2 = findRoot(v - 1); if (root1 != root2) Union(root1, root2); } void check() { int u, v; std::cin >> u >> v; int root1 = findRoot(u - 1); int root2 = findRoot(v - 1); if (root1 == root2) std::cout << "yes" << std::endl; else std::cout << "no" << std::endl; } void stop(int N) { int counter = 0; for (int i = 0; i < N; i++) if (a[i] < 0) counter++; if (counter == 1) std::cout << "The network is connected."; else std::cout << "There are " << counter << " components."; } int main() { int N; char s; std::cin >> N; init(N); do { std::cin >> s; if (s == 'I') connect(); else if (s == 'C') check(); else if (s == 'S') stop(N); } while (s != 'S'); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。