关于并查集问题

Posted wysac666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于并查集问题相关的知识,希望对你有一定的参考价值。

因为从来没有接触过并查集,但是前几天测试中出现了并查集的题,我也开始关注了起来,并且经过几天的研究终于搞懂了.以下是当时的题

7-4 文件传输 (25 分)

当两台计算机双向连通的时候,文件是可以在两台机器间传输的。给定一套计算机网络,请你判断任意两台指定的计算机之间能否传输文件?

输入格式:

首先在第一行给出网络中计算机的总数 N (2N10?4??),于是我们假设这些计算机从 1 到 N 编号。随后每行输入按以下格式给出:

I c1 c2  

其中I表示在计算机c1c2之间加入连线,使它们连通;或者是

C c1 c2    

其中C表示查询计算机c1c2之间能否传输文件;又或者是

S

这里S表示输入终止。

输出格式:

对每个C开头的查询,如果c1c2之间可以传输文件,就在一行中输出"yes",否则输出"no"。当读到终止符时,在一行中输出"The network is connected."如果网络中所有计算机之间都能传输文件;或者输出"There are k components.",其中k是网络中连通集的个数。

输入样例 1:

5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S

输出样例 1:

no
no
yes
There are 2 components.

输入样例 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

输出样例 2:

no
no
yes
yes
The network is connected.
 
作者: 陈越
单位: 浙江大学
时间限制: 150 ms
内存限制: 64 MB
代码长度限制: 16 KB

 这道题乍一看我想到的是DFS,但是在向下继续写的过程中便暴露了很多问题,知道我搞懂了并查集,才发现这题是这么简单

以下是我的代码:

 1 #include<stdio.h>
 2 int pre[10000];//当时少了一个0得注意
 3 int find(int x){
 4     if(pre[x]!=x){
 5         pre[x] = find(pre[x]); //如果自己的老大不是自己,那么就递归继续寻找老大 
 6     }
 7     return pre[x]; //找到老大就返回 
 8 } 
 9 void join(int x,int y){
10     int fx = find(x);
11     int fy = find(y);
12     if(fx!=fy){
13         pre[fx] =  fy; //将两个不同的老大连通 
14     }
15 }
16 int main()
17 {
18     int n;     //一共多少台电脑 
19     char s;   //状态 
20     int a,b;  //电脑名称 
21     int i,j,k;//循环变量 
22     scanf("%d",&n);
23     for(i=0;i<n;i++){
24         pre[i] = i;//初始化电脑状态,每个人都只是与自己连通 
25     }
26     while(~scanf("%c",&s)){
27         if(s==S){
28             break;//输入S程序结束 
29         }
30         scanf("%d %d",&a,&b);//我习惯从0开始 
31         if(s==C){ //查询 
32             if(find(a-1)==find(b-1)){
33                 printf("yes
"); //说明两个老大一样,所以连通 
34             }else{
35                 printf("no
");
36             }
37         }
38         if(s==I){//如果两台机子不连通就让他们连通 
39             join(a-1,b-1); 
40         }
41     }
42     int cut=0;
43     for(i=0;i<n;i++){
44         if(find(i)==i){
45             cut++;
46         }
47     }
48     if(cut==1)printf("The network is connected.");//如果只有一个老大说明大家都连通
49     else printf("There are %d components.",cut); 
50 }

通过这道题,我感觉我要学的东西还有很多,我会一点一点继续学习更多的知识的.

以上是关于关于并查集问题的主要内容,如果未能解决你的问题,请参考以下文章

关于并查集

想要学会并查集吗?看我四十行代码实现它

并查集

关于最小生成树(并查集)prime和kruskal

今天做题做到了并查集相关的内容~简单介绍一下关于并查集的东西

树的应用——并查集及实现代码