您的位置:首页 > Web前端

PAT树 File Transfer——利用不相交集ADT求连通分图数目

2015-11-21 11:28 357 查看
题目描述:

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≤10​4​​),
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
> 0)
n = a
;
return n;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: