题目描述:
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.
也就是一个图里有很多点,输入I c1 c2代表把c1和c2连起来,输入C c1 c2代表询问c1与c2是否在一个连通分图里,需要输出yes或者no,最后再输出连通分图数目,如果整个图都连通那么就输出The network is connected.
由于某一个点只能属于一个连通分图,所以这里用不相交集ADT来做,即为用一个数组存储各个点之间的关系
a[c1]=c2表示c1指向c2,如果c2是一个正数,那么代表一个点,如果c2是一个负数,则代表当前这个连通分图所含点的数目
也就是每个连通分图都用一个“代表点”来表示,沿着一级级的关系可以最终找到这个连通分图的代表点
如果两个点对应的“代表点”相同,那么说明他们在同一个连通分图中。
而且这里合并两个连通分图的时候,为了防止过于倾斜,我们把较小的分图指向较大的分图。
代码如下:
#include <stdio.h>
#include <stdlib.h>
void Initial(int * a, int N);
void Merge(int * a, int i, int j);
int Find(int * a, int n);
int main()
{
int N, temp1, temp2, a[10001];
char order;
scanf("%d", &N);
Initial(a, N);
getchar();
order = getchar();
while(order != 'S'){
scanf("%d%d", &temp1, &temp2);
if(order == 'I')
Merge(a, Find(a, temp1), Find(a, temp2));
else if(order == 'C')
if(Find(a, temp1) == Find(a, temp2))
printf("yes\n");
else
printf("no\n");
getchar();
order = getchar();
}
if(a[0] == 1)
printf("The network is connected.\n");
else
printf("There are %d components.\n", a[0]);
return 0;
}
void Initial(int * a, int N)
{
int i;
a[0] = N;
for(i = 1; i<= N; i++)
a[i] = -1;
}
void Merge(int * a, int i, int j)
{
if(i == j)
return;
if(a[i] < a[j]){
a[i] += a[j];
a[j] = i;
}
else{
a[j] += a[i];
a[i] = j;
}
a[0]--;
}
int Find(int * a, int n)
{
while(a[n] > 0)
n = a[n];
return n;
}