题目描述: 我们有一个计算机网络和一个双向连接列表。这些连接中的每一个都允许文件从一台计算机传输到另一台计算机。是否有可能将文件从网络上的任何一台计算机发送到任何其他计算机?
输入格式: 每个输入文件包含一个测试用例。
对于每个测试用例,第一行包含N (2
⩽
\leqslant
⩽ N
⩽
\leqslant
⩽
1
0
4
10^{4}
104),表示网络中计算机的总数。网络中的每台计算机都用1到N之间的一个正整数表示。
然后在下面几行中,输入以这种格式给出:
I c1 c2
I 表示输入c1和c2之间的连接;或
C c1 c2
其中C表示检查是否有可能在c1和c2之间传输文件;或
S
S代表停止这个实例。
输出格式: 对于每一种C的情况,是否可能或不可能分别在c1和c2之间传输文件,则在一行中打印“yes”或“no”。在每一个实例结束时,如果在任何一对计算机之间有一条路径,打印“The network is connected.”;或者“There are k components.”,其中k为网络中连通组件的个数。
输入样例1:
5 C 3 2 I 3 2 C 1 5 I 4 5 I 2 4 C 3 5 S
输出样例1:
no no yes There are 2 components.
输入样例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
输出样例2:
no no yes yes The network is connected.
解题思路:
★ \bigstar ★ 程序框架搭建:
int main() { 初始化集合; do { 读入一条指令; 处理指令; }while (没结束); return 0; }
int main() { SetType s ; int n; char in; cin >> n ; Initialization (s, n) ; do { cin >> in ; switch (in){ case 'I': Input_connection (s); break; //Union(Find) case 'C': Check_connection (s); break; //Find case 'S': Check_network(s, n); break; //数集合的根 } }while ( in != 'S'); return 0; }
代码实现:
#include<iostream> using namespace std; #define MaxSize 10005 typedef int SetType; // 初始化 void Init(SetType s[], int n) { for (int i = 0; i < n; i++) s[i] = -1; } // 查找(路径压缩) int Find(SetType s[], int x) { if (s[x] < 0) // 本身已经是根 return x; else // 1. 找到根 2. 把根变成x的父结点 3.再返回根 return s[x] = Find(s, s[x]); } // 并(比规模:把小树贴到大树上) void Union(SetType s[], int x1, int x2) { // x1规模更大,负数 if (s[x1] < s[x2]) { s[x1] += s[x2]; // 两树合并,规模相加 s[x2] = x1; // x2挂到x1上 } else { s[x2] += s[x1]; // 两树合并,规模相加 s[x1] = x2; } } //连接 void Input_connection(SetType s[]) { int x1, x2; cin >> x1 >> x2; int root1 = Find(s, x1 - 1); // 以数组下标存值,下标与存值差 1 int root2 = Find(s, x2 - 1); if (root1 != root2) Union(s, root1, root2); } //检查连接 void check_connection(SetType s[]) { int x1, x2; cin >> x1 >> x2; int root1 = Find(s, x1 - 1); int root2 = Find(s, x2 - 1); if (root1 == root2) cout << "yes" << endl; else cout << "no" << endl; } // 检查网络 void check_network(SetType s[], int n) { int counter = 0; for (int i = 0; i < n; i++) if (s[i] < 0) counter++; if (counter == 1) cout << "The network is connected."; else cout << "There are " << counter << " components."; } int main() { int n; char in; cin >> n; SetType s[MaxSize]; Init(s, n); do { getchar(); // 接收每次多出来的回车 cin >> in; switch (in) { case 'I':Input_connection(s); break; case 'C':check_connection(s); break; case 'S':check_network(s, n); break; } } while (in != 'S'); system("pause"); return 0; }
测试: