• PTA 5-8 File Transfer (25)


    题目: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.  即中间图中的对应操作的结果

    过程:image     输入:image对应的树:image

    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;
    }
    
  • 相关阅读:
    Elasticsearchheader、Kibana实现对ES的可视化
    记录Elasticsearch 分片恢复问题
    跨域问题处理手册
    MySQLJSON与虚拟列结合使用提升性能
    Mysql 备份恢复与xtrabackup备份
    Delphi中将ShowMessage,MessageDlg, MessageBox,InputBox,InputQuery及任意模态窗口相对主窗口(父窗口、母窗口)居中
    Python里的引用与拷贝规律
    「Codeforces 1644F」Basis
    记录
    swift 标签2
  • 原文地址:https://www.cnblogs.com/claremore/p/4811714.html
Copyright © 2020-2023  润新知