File Transfer(并查集)
题目大意:将多个电脑通过网线连接起来,不断查询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≤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.
思路: 并查集的题目,首先知道如何表示并查集的数据结构:
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(并查集)的更多相关文章
- 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 ...
- 04-树5. File Transfer--并查集
对于一个集合常见的操作有:判断一个元素是否属于一个集合:合并两个集合等等.而并查集是处理一些不相交集合(Disjoint Sets)的合并及查询问题的有利工具. 并查集是利用树结构实现的.一个集合用一 ...
- Uva 12361 File Retrieval 后缀数组+并查集
题意:有F个单词,1 <= F <=60 , 长度<=10^4, 每次可以输入一个字符串,所有包含该字串的单词会形成一个集合. 问最多能形成多少个不同的集合.集合不能为空. 分析:用 ...
- 05-树8 File Transfer
并查集 简单并查集:输入N,代表有编号为1.2.3……N电脑.下标从1开始.初始化为-1.合并后根为负数,负数代表根,其绝对值代表个数. We have a network of computers ...
- pat04-树5. File Transfer (25)
04-树5. File Transfer (25) 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue We have ...
- 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 ...
- *HDU2473 并查集
Junk-Mail Filter Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- [并查集] POJ 1611 The Suspects
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 35206 Accepted: 17097 De ...
- PAT 5-8 File Transfer (25分)
We have a network of computers and a list of bi-directional connections. Each of these connections a ...
随机推荐
- 大话Linux内核中锁机制之完成量、互斥量
大话Linux内核中锁机制之完成量.互斥量 在上一篇博文中笔者分析了关于信号量.读写信号量的使用及源码实现,接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题. 八.完成量 下面讨论完成量的内 ...
- Oracle 的PL/SQL语言使用
--PL/SQL语言(procedure language 过程化语言) --1.声明类型 declare k number; m ; --Character String buffer too sm ...
- iOS中怎么判断可变和不可变的坑(更正版)
iOS中怎么判断可变和不可变的坑 怎么判断NSString和NSMutableString呢 看题 BOOL result = [" isKindOfClass:[NSMutableStri ...
- ZJOI2008]树的统计(树链剖分,线段树)
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- 【TOJ 1072】编辑距离(动态规划)
描述 假设字符串的基本操作仅为:删除一个字符.插入一个字符和将一个字符修改成另一个字符这三种操作. 我们把进行了一次上述三种操作的任意一种操作称为进行了一步字符基本操作. 下面我们定义两个字符串的编辑 ...
- 19-3-7Python中小数据池、数据类型的补充、set集合
一.小数据池(了解) “id” 获取内存地址 “==” 比较等号两端的值是否相等 “is” 身份运算:判断的是两个对象的内存地址是否相同. 代码块:一个文件就是一个代码块.(函数.类都是 ...
- js 变量声明易混淆的几点知识
这是我 JavaScript 学习过程中遇到的一些容易混淆的地方,趁着有时间,做了一个整理. 变量提升 变量与函数名提升优先级 js 作用域内有变量,这个很好理解,但有一些细节需要注意. consol ...
- Redis全方位详解--磁盘持久化和容灾备份
序言 在上一篇博客中,博客介绍了redis的数据类型使用场景和redis分布式锁的正确姿势.我们知道一旦Redis重启,存在redis里面的数据就会全部丢失.所以这篇博客中向大家介绍Redis的磁盘持 ...
- Redis开启远程访问及密码认证
配置 redis.conf 文件 [root@localhost bin]# vi /usr/local/redis/bin/redis.conf 将 bind 127.0.0.1 注释掉 将 pro ...
- python学习——简介和入门
一.Python简介: Python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为AB ...