题目大意:将多个电脑通过网线连接起来,不断查询2台电脑之间是否连通。

问题来源:中国大学mooc

05-树8 File Transfer (25 分)

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 kcomponents." 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.

思路: 并查集的题目,首先知道如何表示并查集的数据结构:

typedef struct{
  int data;
  int parent;
}SetType[MaxSize];
本题可以进行优化:只用一个数组  int SetType[MaxSize]表示即可,数组下标表示计算机的序号,SetType[index]表示为他的父节点,就是连通节点的序号。
并查集的Find  和union函数如下:
int Find(SetType S[],int x){
int i;
for(i=;i<MaxSize&&S[i].data!=x;i++); //查找的时间复杂度n
if(i>MaxSize)return -;
for(;S[i].parent>=;i=S[i].parent);
return i; //找到X所属集合,返回树根结点在数组S中的下标
} void Union(SetType S[],int x1,int x2){
int root1,root2;
root1=find(S,x1);
root2=find(S,x2);
if(root1!=root2)S[root2]=root1; }

优化后的Find和路径压缩函数如下:

#define Maxitem 10000

int S[Maxitem];
//采用路径压缩,尾递归寻找他的根结点
int find(int x){
if(S[x]<)return x;
////先找到根; 把根变成 X 的父结点; 再返回根。
else return S[x]=find(S[x]);
}
//按秩归并,将根结点数量少的树连接到根结点多的树,这里用S[root]表示根结点
//S[root]为负数,绝对值为节点数
void Union(int root1,int root2){
if(S[root1]>S[root2]){
S[root2]+=S[root1];
S[root1]=root2;
}else {
S[root1]+=S[root2];
S[root2]=root1;
}
}

程序框架:

最终代码如下:

#include<cstdio>
#define Maxitem 10000 int S[Maxitem];
//采用路径压缩,尾递归寻找他的根结点
int find(int x){
if(S[x]<)return x;
////先找到根; 把根变成 X 的父结点; 再返回根。
else return S[x]=find(S[x]);
}
//按秩归并,将根结点数量少的树连接到根结点多的树,这里用S[root]表示根结点
//S[root]为负数,绝对值为节点数
void Union(int root1,int root2){
if(S[root1]>S[root2]){
S[root2]+=S[root1];
S[root1]=root2;
}else {
S[root1]+=S[root2];
S[root2]=root1;
}
}
void initialzation(int n){
for(int i=;i<n;i++){
S[i]=-;
}
}
void Input_connection(){
int u,v,root1,root2;
scanf("%d %d",&u,&v);
getchar();
root1=find(u-);
root2=find(v-);
Union(root1,root2);
}
void Check_connection(){
int u,v,root1,root2;
scanf("%d %d",&u,&v);
getchar();
root1=find(u-);
root2=find(v-);
if(root1==root2)printf("yes\n");
else printf("no\n");
}
void Check_networks(int n){
int count=;
for(int i=;i<n;i++)
if(S[i]<)count++;
if(count==)printf("The network is connected.\n");
else printf("There are %d components.\n",count);
}
int main(){
char in;
int n;
scanf("%d",&n);
initialzation(n);
do{
scanf("%c",&in);
switch(in){
case'I':Input_connection();break;
case'C':Check_connection();break;
case'S':Check_networks(n);break;
}
}while(in!='S');
return ;
}
 

File Transfer(并查集)的更多相关文章

  1. 05-树8 File Transfer(25 point(s)) 【并查集】

    05-树8 File Transfer(25 point(s)) We have a network of computers and a list of bi-directional connect ...

  2. 04-树5. File Transfer--并查集

    对于一个集合常见的操作有:判断一个元素是否属于一个集合:合并两个集合等等.而并查集是处理一些不相交集合(Disjoint Sets)的合并及查询问题的有利工具. 并查集是利用树结构实现的.一个集合用一 ...

  3. Uva 12361 File Retrieval 后缀数组+并查集

    题意:有F个单词,1 <= F <=60 , 长度<=10^4, 每次可以输入一个字符串,所有包含该字串的单词会形成一个集合. 问最多能形成多少个不同的集合.集合不能为空. 分析:用 ...

  4. 05-树8 File Transfer

    并查集 简单并查集:输入N,代表有编号为1.2.3……N电脑.下标从1开始.初始化为-1.合并后根为负数,负数代表根,其绝对值代表个数. We have a network of computers ...

  5. pat04-树5. File Transfer (25)

    04-树5. File Transfer (25) 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue We have ...

  6. PTA 05-树8 File Transfer (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/670 5-8 File Transfer   (25分) We have a netwo ...

  7. *HDU2473 并查集

    Junk-Mail Filter Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. [并查集] POJ 1611 The Suspects

    The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 35206   Accepted: 17097 De ...

  9. PAT 5-8 File Transfer (25分)

    We have a network of computers and a list of bi-directional connections. Each of these connections a ...

随机推荐

  1. [LuoguP1360][USACP07MAR]黄金阵容均衡

    [LuoguP1360][USACP07MAR]黄金阵容均衡(Link) 每天会增加一个数\(A\),将\(A\)二进制分解为\(a[i]\),对于每一个\(i\)都增加\(a[i]\),如果一段时间 ...

  2. CodeForces - 999D Equalize the Remainders (模拟+set)

    You are given an array consisting of nn integers a1,a2,…,ana1,a2,…,an , and a positive integer mm . ...

  3. HDU 1058(打表)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1058 Humble Numbers Time Limit: 2000/1000 MS (Java/O ...

  4. 安卓 通过www读取Application.persistentDataPath

    今天在读取Application.persistentDataPath路径下的图片时,在前面加上“file:///” 例如 #if UNITY_EDITOR || UNITY_STANDALONE r ...

  5. linux内核追踪(trace)(QEMU+gdb)

    1.引言 Linux内核是一个很大的模块,如果只是看源码有时会难以理解Linux内核的一些代码设计情况,如果可以结合Linux内核运行同时阅读源码再好不过,本文大致介绍Linux内核追踪方式,采用工具 ...

  6. react 配置开发环境

    一:先自行下载安装node和npm 二:cnpm install create-react-app -g 三:create-react-app my-project 四:cd my-project  ...

  7. c++友元函数、友元类、友成员函数

    友元函数:不是类成员函数,是一个类外的函数,但是可以访问类所有成员. class Point{ public: friend void fun(Point t);//友元函数 private: int ...

  8. HCDA day1

    OSI有几层: OSI将计算机网络体系结构(architecture)划分为以下七层: 图1.OSI模型 物理层: 将数据转换为可通过物理介质传送的电子信号 相当于邮局中的搬运工人. 物理层(Phys ...

  9. VS Code 的常用快捷键及插件(前端)

    一.vs code 的常用快捷键 1.注释: a) 单行注释:[ctrl+k,ctrl+c] 或 ctrl+/ b) 取消单行注释:[ctrl+k,ctrl+u] (按下ctrl不放,再按k + u) ...

  10. Python中读取文件输出时在头部输出\ufeff

    问题出现: 在我测试python中的文本文件的读取与写入时,用到了字典对象来存储读出的数据. std_data = dict() with open(sys.argv[1], encoding='UT ...