7-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.
思路:
1、考察集合并查操作,计算机连在一起意思就是一个集合,即有相同的根节点。
2、查找操作find(s,x),返回x的根在数组中位置下标。并操作union,把一个元素的根连在另一元素的根上。TSSN做法。
3、按秩归并,可以降低整体时间复杂度,可以按树的高度归并,也可以按树的节点数量归并。数组中根节点存储的不在是-1.而是树的高度或者树的节点数量。
4、压缩路径,即把元素直接连接在根节点上,降低了树的高度,用递归实现,但在java中效率并不高。适合C语言,因为c会把递归自动编译成一个循环,java不会,递归会造成大量的开销,得不偿失。
5、component 连通集。
6、写代码的时候,随时随地用一个特例验证下,写一段验证一段,可以避免很多低级错误。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int S[] = new int[n];
for(int i=0;i<n;i++) {
S[i]=-1;
}
char ch = 0 ;
do {
ch = in.next().charAt(0);
switch (ch){
case 'C':check_connections(S,in);break;
case 'I':input_connections(S,in);break;
case 'S':check_network(S);break;
}
}while(ch!='S');
}
private static void check_network(int[] s) {
// TODO Auto-generated method stub
int count=0;
for(int i=0;i<s.length;i++) {
if(s[i]<0)
count++;
}
if(count==1)
System.out.println("The network is connected.");
else
System.out.println("There are "+count+" components.");
}
private static void input_connections(int[] s,Scanner in) {
// TODO Auto-generated method stub
int num1= in.nextInt();
int num2=in.nextInt();
int root1=find(s,num1);
int root2=find(s,num2);
if(root1!=root2) {
if(Math.abs(s[root1])<=Math.abs(s[root2])) {
int temp = s[root1];
s[root1]=root2;
s[root2]=s[root2]+temp;
}
else {
int temp =s[root2];
s[root2]=root1;
s[root1]=s[root1]+temp;
}
}
}
private static void check_connections(int[] s,Scanner in) {
// TODO Auto-generated method stub
int num1 = in.nextInt();
int num2= in.nextInt();
int root1=find(s,num1);
int root2=find(s,num2);
if(root1==root2) {
System.out.println("yes");
}
else
System.out.println("no");
}
private static int find(int[] s, int num) { //返回根节点在数组中的位置下标
// TODO Auto-generated method stub
num--;
while(num>=0&&s[num]>=0) {
num = s[num];
}
return num;
// int i=num-1;
// if(s[i]<0)
// return i;
// else {
// return s[i]=find(s,s[i]+1); //路径压缩
// }
}
}