• 05-树8 File Transfer 并查集(按秩归并+路径压缩)


    复杂度分析
    https://blog.csdn.net/Estia_/article/details/86708289

    e 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.
    
    主要思想:
    1 按秩归并:1比较树高度归并 2 比较树规模归并 这里采用后者 后者配合路径压缩更好因为路径压缩会改变树高
    2 数组根节点(老大)的值存有多少个节点(小弟+自己)的负数,而小弟结点的值是指向老大的值(正数)
    #include<iostream>                                   
    using namespace std;
    int set[10001];
    void Union(int s[], int root1,int root2)           
    {												   //将数组根节点(老大)的值存有多少个节点(小弟+自己)的负数
    	if (s[root2] < s[root1]) {                     //如果集合2比集合规模1大,1并入2中
    		s[root2] += s[root1];
    		s[root1] = root2;  
    	}
    	else {
    		s[root1] += s[root2];						//如果集合1比集合规模2大,2并入1中
    		s[root2] = root1;
    	}
    }
    int find(int s[], int x)
    {
    	if (s[x] < 0)                                    //指向的父亲结点的值记录着个数的负数
    		return x;									 //返回根节点的下标
    	else
    		return s[x] = find(s, s[x]);                 //递归,路径压缩,使得下次判断查找根节点十分方便
    	                                                 //给每个结点都指向他的根节点,一路上都会被压缩
    }
    int main()
    {
    	int n;
    	int num = 0;
    	int computerA, computreB;
    	cin >> n;
    	for (int i = 0; i < n + 1; i++)
    		set[i] = -1;                                      //一开始都是只有自己1个结点,所以为-1
    	char input;
    	while (cin >> input&&input != 'S') {
    		if (input == 'I') {
    			cin >> computerA >> computreB;
    			Union(set, find(set, computerA), find(set, computreB));
    		}else if (input == 'C') {
    			cin >> computerA >> computreB;
    			if (find(set, computerA) == find(set, computreB))
    				cout << "yes" << endl;
    			else
    				cout << "no" << endl;
    		}
    	}
    	for (int i = 1; i < n + 1; i++) {
    		if (set[i] < 0)
    			num++;
    	}
    	if (num == 1)
    		cout << "The network is connected." << endl;
    	else
    		cout << "There are " << num << " components." << endl;
    	return 0;
    }
    
  • 相关阅读:
    SpringBoot-整合多数据源
    SpringBoot-整合@transactional注解
    SpringBoot-整合mybatis
    SpringBoot-区分不同环境配置文件
    SpringBoot-@value自定义参数
    SpringBoot-@async异步执行方法
    bias与variance,欠拟合与过拟合关系
    从贝叶斯到深度学习各个算法
    基础机器学习算法
    推荐算法总结
  • 原文地址:https://www.cnblogs.com/Hsiung123/p/13109999.html
Copyright © 2020-2023  润新知