码迷,mamicode.com
首页 > 编程语言 > 详细

PTA 5-8(English) File Transfer (25) - 并查集 - 数组实现

时间:2015-09-15 23:22:56      阅读:465      评论:0      收藏:0      [点我收藏+]

标签:

题目:http://pta.patest.cn/pta/test/16/exam/4/question/670

PTA - Data Structures and Algorithms (English) - 5-8

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

 

解法转自:http://www.cnblogs.com/clevercong/p/4192953.html

题目分析:

  首先输入的是一个整型数,代表网络中有多少个computer(结点)。

  然后输入若干行,每行由1个字符,两个整数组成。I 代表增加连接,C 代表检查是否连接,S 代表结束输入。

  C 检查连接的时候,要输出yes或者no说明是否连通。

  最后输出整个网络的情况,如果全部连通则输出The network is connected.,否则输出有多少个连通分量。

算法示例:

注:左图中 1.  2.  3.  4.  5.  即中间图中的对应操作的结果

过程:技术分享     输入:技术分享对应的树:技术分享

 

1.初始化

int *S;   //全局变量定义
// 在main函数中动态申请S
S = new int[num+1];   //num+1方便从1开始查起
for(int i=0; i<=num; i++)
    S[i] = i;   //数组下标即Data,数组值为Parent

2.“I”和“C”操作

if(choose == ‘I‘)
    Union(c1, c2);
if(choose == ‘C‘)
{
    if(Find(c1) == Find(c2)) //根相同,即在一个集合中
        cout << "yes" << endl;
    else
        cout << "no" << endl;
}

3.查

int Find( ElementType X ) //找X所在集合的根结点
{
    if(S[X]==X)
        return X;
    return S[X]=Find(S[X]); //向上一直找根,把根赋给S[X]即把结点直接连到根上,使当前树高化为1
}

4.并

void Union( ElementType X1, ElementType X2) //把X1和X2合并到一个并查集中(增加连接)
{
    int Root1, Root2;
    Root1 = Find(X1);
    Root2 = Find(X2);
    if ( Root1 != Root2 )  //!根不相等时才合并
    {
        //!数字大的连到小的上面去
        if(S[Root1] < S[Root2])
            S[Root2] = Root1;
        else
            S[Root1] = Root2;
    }
}

5.求连通分量个数

for(int i=1; i<=num; i++)
{
    if(S[i] == i)   //如果Parent就是Data它自己,即为根结点
    icount++;
}

完整代码:

#include <iostream>
using namespace std;

int *S;

//!找x所在集合的根结点
int Find( int X )
{
    if(S[X]==X)
        return X;
    return S[X]=Find(S[X]); //!向上一直找根,同时把当前结点直接连到根,树的高度化为1
}

void Union( int X1, int X2)
{
    int Root1, Root2;
    Root1 = Find(X1);
    Root2 = Find(X2);
    
    if ( Root1 != Root2 ) //!根不相等时才合并
    {
        //!数字大的连到小的上面去
        if(S[Root1] < S[Root2])
            S[Root2] = Root1;
        else
            S[Root1] = Root2;
    }
}

int main()
{
    int num;
    cin >> num;
    char choose;
    int c1, c2;
    S = new int[num+1]; //!从1开始,方便查找,so一共num+1

    //!初始化:数组角标即Data,值为Parent
    for(int i=0; i<=num; i++)
        S[i] = i;
    while(1)
    {
        cin >> choose;
        if(choose == ‘S‘)
            break;
        cin >> c1 >> c2;
        if(choose == ‘I‘)
            Union(c1, c2);
        if(choose == ‘C‘)
        {
            if(Find(c1) == Find(c2))
                cout << "yes" << endl;
            else
                cout << "no" << endl;
        }
    }
    int icount=0; //记录有多少个连通分量
    for(int i=1; i<=num; i++)
    {
        if(S[i] == i)   //!如果Parent就Data它自己,证明是根结点
            icount++;
    }
    if(icount == 1)
        cout << "The network is connected." << endl;
    else
        cout << "There are " << icount << " components." << endl;
    return 0;
}

PTA 5-8(English) File Transfer (25) - 并查集 - 数组实现

标签:

原文地址:http://www.cnblogs.com/claremore/p/4811714.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!