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.
解题思路:
此问题可用并查集求解。
查找两个电脑是否相连,只需访问他们的根是否相同即可。
所求结果若是电脑全部相连,即所有的数字对应的根相同,输出 "The network is connected." ;
否则就输出有几个连接的集合,这里我用map函数来统计。
代码如下:
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
typedef struct node
{
int data;
int rank;
int parent;
}UFSTree;
void MAKE_SET(UFSTree t[], int n)
{
int i;
for (i = 0; i <= n; i++)
{
t[i].data = i;
t[i].rank = 0;
t[i].parent = i;
}
}
int FIND_SET(UFSTree t[], int x)
{
if (x != t[x].parent)
return(FIND_SET(t, t[x].parent));
else
return x;
}
void UNION(UFSTree t[], int x, int y)
{
x = FIND_SET(t, x);
y = FIND_SET(t, y);
if (t[x].rank > t[y].rank)
t[y].parent = x;
else
{
t[x].parent = y;
if (t[x].rank == t[y].rank)
t[y].rank++;
}
}
int main()
{
int N;
cin >> N;
UFSTree P[10001];
MAKE_SET(P, N);
while (1)
{
char c;
cin >> c;
if (c == 'S')
break;
int a, b;
cin >> a >> b;
if (c == 'I')
UNION(P, a, b);
else if (FIND_SET(P, a) == FIND_SET(P, b))
cout << "yes" << endl;
else
cout << "no" << endl;
}
map<int, int>mp;
int sum = 0;
for (int i = 1; i <= N; i++)
{
if (!mp.count(FIND_SET(P, i)))
{
mp[FIND_SET(P, i)] = 1;
sum++;
}
}
if (sum == 1)
cout << "The network is connected." << endl;
else
cout << "There are "<<sum<<" components." << endl;
return 0;
}