中国大学MOOC-数据结构基础习题集、04-2、File Transfer

题目链接:http://www.patest.cn/contests/mooc-ds/04-2

题目分析:这是一道考察“并查集”的问题,通过的人像2-1一样那么少。

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

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

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

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

特别说明:这道题比较坑爹,需要有几个点特别注意一下:

  1) 如果你用老师给的Find函数,那你就废废了,那个函数的时间复杂度绝对不能让你AC。不仅吐槽一下。必须要自己写一个,很简单,代码如下:

int Find( ElementType X )
{
    if(S[X]==X)
        return X;
    return S[X]=Find(S[X]);
}

2) 不需要像课上讲的一样,定义一个结构体,一个是数据区,一个是父结点区,只用一个一维数组就够了!为了方便,我们定义数组的长度比正常的大1,这样方便我们从1开始查起。   
// 全局变量定义
int *S;
// 在main函数中动态申请
S = new int[num+1];
3) Union的时候不需要考虑哪个子树大,哪个子树小,并不影响你AC。但是如果考虑的话更好,到底能提高多少速度自己实践下就知道了。
void Union( ElementType X1, ElementType 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;
        }
    }
}

代码分析:

头文件及全局变量声明:1~5行。这里我们用ElementType代替int,是因为从老师那里拷的算法,用的就是ElementType,各位编写的时候无视就可以了。

Find函数和Union函数:6~30行。上面已经详细说过了,各位看看就好。

主函数输入及输出:31~65行。虽然看起来比较多,但是还是很简单的。

#include <iostream>
#define ElementType int
using namespace std;

int *S;
int Find( ElementType X )
{
    if(S[X]==X)
        return X;
    return S[X]=Find(S[X]);
}

void Union( ElementType X1, ElementType 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];
    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就它自己,证明是根结点
            icount++;
    if(icount == 1)
        cout << "The network is connected." << endl;
    else
        cout << "There are " << icount << " components." << endl;
    return 0;
}
文章转载自http://www.cnblogs.com/clevercong/p/4192953.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值