题目:https://pintia.cn/problem-sets/1268384564738605056/problems/1278908289143574529
We have a network of computers and a list of bi-directional connections. Each of these connections allows a file transfer from one computer to another. Is it possible to send a file from any computer on the network to any other?
Input Specification:
Each input file contains one test case. For each test case, the first line contains N (2≤N≤104), the total number of computers in a network. Each computer in the network is then represented by a positive integer between 1 and N. Then in the following lines, the input is given in the format:
I c1 c2
where I
stands for inputting a connection between c1
and c2
; or
C c1 c2
where C
stands for checking if it is possible to transfer files between c1
and c2
; or
S
where S
stands for stopping this case.
Output Specification:
For each C
case, print in one line the word "yes" or "no" if it is possible or impossible to transfer files between c1
and c2
, respectively. At the end of each case, print in one line "The network is connected." if there is a path between any pair of computers; or "There are k
components." where k
is the number of connected components in this network.
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.
题解:
https://www.cnblogs.com/liangchao/p/4286451.html
代码:
#include <iostream> #include <string> using namespace std; #define MaxNum 10001 int Find( int arrSet[], int X ); void ConnectSet( int arrSet[], int c1, int c2 ); string CheckConnection( int arrSet[], int c1, int c2 ); int CountComponentNum( int arrSet[], int num ); //使用数组保存集合元素,数组下标对应元素值,数组元素对应parent值 int main() { int nodeNum; int *arrSet; cin >> nodeNum; nodeNum += 1; //由于数组下标0用于标记根结点,因此使用数组下标从1开始 arrSet = new int[ nodeNum ]; //parent == 0 -> root, parent == -1 -> NULL int i; for ( i = 0; i < nodeNum; i++ ) { arrSet[i] = -1; } int c1; int c2; string operationName; string checkResult = ""; int componentNum; while( true ) { cin >> operationName; if ( operationName == "S" ) { break; } cin >> c1 >> c2; if ( operationName == "I" ) { ConnectSet( arrSet, c1, c2 ); } else if ( operationName == "C" ) { checkResult += CheckConnection( arrSet, c1, c2 ); } } cout << checkResult; componentNum = CountComponentNum( arrSet, nodeNum ); if ( componentNum == 1 ) { cout << "The network is connected." << endl; } else { cout << "There are " << componentNum << " components." << endl; } } int Find( int arrSet[], int X ) //在查找过程中,减少树的高度 { if ( X > MaxNum || arrSet[X] == -1 ) { return -1; } int temp = X; int exchange; while( arrSet[X] > 0 ) { X = arrSet[X]; } while ( arrSet[arrSet[temp]] > 0 ) //将搜索路径中的所有元素都直接指向根结点 { exchange = temp; temp = arrSet[temp]; arrSet[exchange] = X; } return X; } void ConnectSet( int arrSet[], int c1, int c2 ) { int root1, root2; if ( arrSet[c1] == -1 ) { arrSet[c1] = 0; root1 = c1; } else { root1 = Find( arrSet, c1 ); } if ( arrSet[c2] == -1 ) { arrSet[c2] = 0; root2 = c2; } else { root2 = Find( arrSet, c2 ); } if ( root1 != root2 ) { arrSet[root2] = root1; } } string CheckConnection( int arrSet[], int c1, int c2 ) { int root1, root2; root1 = Find( arrSet, c1 ); root2 = Find( arrSet, c2 ); if ( root1 == root2 && root1 != -1 && root2 != -1 ) { return "yes\n"; } else { return "no\n"; } } //计算数组中的集合个数 int CountComponentNum( int arrSet[], int num ) { int i; int sum = 0; int nodeNum = 0; for( i = 0; i < num; i++ ) { if ( arrSet[i] >= 0 ) //统计所有结点数量 { nodeNum++; } if ( arrSet[i] == 0 ) //根结点的数量 { sum++; } } return sum + num - 1 - nodeNum; //给出的结点数中,可能存在未包含进任何集合的结点 //这里-1是由于在一开始将nodeNum加了1,这个处理需要改进 }