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?
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.
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.
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S
no
no
yes
There are 2 components.
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
no
no
yes
yes
The network is connected.
Case | Hint | Result | Run Time | Memory |
---|---|---|---|---|
0 | sample 1 合并2个集合,最后不连通 | Accepted | 3 ms | 424 KB |
1 | sample 2 最后连通 | Accepted | 2 ms | 384 KB |
2 | 最小N,无连通操作 | Accepted | 3 ms | 384 KB |
3 | 最大N,无操作 | Accepted | 2 ms | 540 KB |
4 | 最大N,递增链,卡不按大小union的 | Accepted | 43 ms | 424 KB |
5 | 最大N,递减链,卡不按大小union的 | Accepted | 49 ms | 424 KB |
6 | 最大N,两两合并,反复查最深结点,卡不压缩路径的 | Accepted | 49 ms | 412 KB |
#include
using namespace std;
#define MaxSize 10000
typedef int SetType[MaxSize];
void initializeSet(SetType S, int N);
void Check(SetType S);
int Find(SetType S, int X);
void Connect(SetType S);
void Union(SetType S, int Root1, int Root2);
void Stop(SetType S, int N);
/*测试数据1
//输入操作
char Operation[7] = {'C','I','C','I','I','C','S'};
//输入结点的下标
int InputIndex[7][2] = \
{ {3,2},
{3,2},
{1,5},
{4,5},
{2,4},
{3,5},
{0,0}};
int i = 0;
*/
/*测试数据2
//输入操作
char Operation[9] = {'C','I','C','I','I','C','I','C','S'};
//输入结点的下标
int InputIndex[9][2] = \
{ {3,2},
{3,2},
{1,5},
{4,5},
{2,4},
{3,5},
{1,3},
{1,5},
{0,0}};
int i = 0;
*/
int main()
{
/*测试程序
SetType S;
char Ope;
//输入总结点个数
static int N = 5;
//初始化集合数组
initializeSet(S, N);
do{
Ope = Operation[i];
switch(Ope){
case 'C': Check(S); break;
case 'I': Connect(S); break;
case 'S': Stop(S, N); break;
}
++i;
}while(Ope != 'S');
*/
//正式应用
SetType S;
char Ope;
int N;
//输入总结点个数
cin >> N;
//初始化集合数组
initializeSet(S, N);
do{
cin >> Ope;
switch(Ope){
case 'C': Check(S); break;
case 'I': Connect(S); break;
case 'S': Stop(S, N); break;
}
}while(Ope != 'S');
return 0;
}
void initializeSet(SetType S, int N)
{
for(int i=0; i> u;
cin >> v;
//由于数组第一下标为0,而输入第一下标为1
Root1 = Find(S, u-1);
Root2 = Find(S, v-1);
if(Root1 == Root2){
cout << "yes" <> u;
cin >> v;
//由于数组第一下标为0,而输入第一下标为1
Root1 = Find(S, u-1);
Root2 = Find(S, v-1);
//两个根相等的集合不需要再连接
if(Root1 != Root2){
Union(S, Root1, Root2);
}
}
void Union(SetType S, int Root1, int Root2)
{
//由于根结点保存的父结点值为负数,
//其绝对值表示该集合的元素个数,
//因此规模大的集合,其值小
if(S[Root1] < S[Root2]){
//Root1集合的元素更多,规模更大
//更新新集合的元素个数
S[Root1] = S[Root1] + S[Root2];
S[Root2] = Root1;
}
else{
S[Root2] = S[Root1] + S[Root2];
S[Root1] = Root2;
}
}
void Stop(SetType S, int N)
{
int components = 0;
for(int n=0; n