并查集

作者: Allen的光影天地 | 来源:发表于2018-11-24 19:57 被阅读3次

关键的两个函数:查找和合并。有很多查找时间的方法

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

答案

//
// Created by allenhsu on 2018/11/24.
//

#include <iostream>
using namespace std;
// 找到X的根节点
int Find(int S[], int X){
    for (; S[X] >= 0; X = S[X]);
    return X;
}

void Union(int S[], int Root1, int Root2){
    if (S[Root1] > S[Root2]){
        S[Root1] = Root2;
    }else {
        if (S[Root1] == S[Root2]) S[Root1]--;
        S[Root2] = Root1;
    }
}

void Input_connection(int S[]){
    int u, v;
    int root1, root2;
    cin >> u >> v;
    root1 = Find(S, u-1);
    root2 = Find(S, v-1);
    if (root1 != root2){
        Union(S, root1, root2);
    }
}

void Check_connection(int S[]){
    int u, v;
    cin >> u >> v;
    int root1, root2;
    root1 = Find(S, u-1);
    root2 = Find(S, v-1);
    if (root1 != root2){
        cout << "no" << endl;
    }else cout << "yes" << endl;
}

int Check_network(int S[], int n){
    int count = 0;

    for (int i = 0; i < n; ++i) {
        if (S[i] < 0) count++;
    }
    if (count == 1) cout << "The network is connected." << endl;
    else cout << "There are " << count << " components." << endl;

    return 0;
}
int main(){
    int n;
    cin >> n;
    int S[10000];
    for (int i = 0; i < n; ++i) {
        S[i] = -1;
    }
    char in = '\0';
    while (in != 'S'){
        cin >> in;
        switch (in){
            case 'I': Input_connection(S); break;
            case 'C': Check_connection(S); break;
            case 'S': Check_network(S, n); break;
        }
    }
    return 0;
}

相关文章

  • markdown学习

    #并查集 ##并查集的定义 ##并查集的操作

  • 算法模板(四)并查集

    并查集 路径压缩并查集

  • 并查集入门使用

    本文参考自《算法笔记》并查集篇 并查集的定义 什么是并查集?并查集可以理解为是一种维护数据集合的结构。名字中并查集...

  • 并查集练习

    并查集 参考《算法笔记》 三要素:并,查,集。 并差集与一个算法有关,kruskal算法,就可通过并查集实现。 1...

  • 并查集

    并查集 并查集是什么 并查集是一种用来管理元素分组情况的数据结构,并查集可以高效地进行如下操作: 查询元素a和元素...

  • 数据结构与算法(十二)并查集(Union Find)

    本文主要包括以下内容: 并查集的概念 并查集的操作 并查集的实现和优化Quick FindQuick Union基...

  • 并查集

    并查集是什么 并查集是一种用来管理元素分组情况的数据结构。并查集可以高效地进行如下操作。不过需要注意并查集虽然可以...

  • 并查集

    开始时让每个元素构成一个个单元素集合(注意初始化时应使每个元素各成一组)按照一定顺序将属于同一组元素所在的集合合并...

  • 并查集

  • 并查集

    并查集 https://blog.csdn.net/liujian20150808/article/details...

网友评论

      本文标题:并查集

      本文链接:https://www.haomeiwen.com/subject/kxpeqqtx.html