数据结构大作业——并查集:检查网络

本文介绍了如何使用并查集数据结构来解决计算机网络中判断任意两台计算机之间是否可以进行文件传输的问题。根据输入的计算机数量和连接关系,程序需要检查指定计算机之间的连通性,并在所有计算机间都可传输文件时输出特定提示。通过引入路径压缩优化,实现了高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

11并查集:检查网络

问题描述】

给定一个计算机网络以及机器间的双向连线列表,每一条连线允许两端的计算机进行直接的文件传输,其他计算机间若存在一条连通路径,也可以进行间接的文件传输。请写出程序判断:任意指定两台计算机,它们之间是否可以进行文件传输?

【输入要求】

输入若干测试数据组成。对于每一组测试,第1行包含一个整数N(≤10000),即网络中计算机的总台数,因而每台计算机可用1到N之间的一个正整数表示。接下来的几行输入格式为I C1 C2或者 C或者C C1C2或者S,其中C1和C2是两台计算机的序号,I表示在C1和C2间输入一条连线,C表示检查C1和C2间是否可以传输文件,S表示该组测试结束。当N为0时,表示全部测试结束,不要对该数据做任何处理。

输出要求

对每一组C开头的测试,检查C1和C2间是否可以传输文件,若可以,则在一行中输出“yes”,否则输出“no”。当读到S时,检查整个网络。若网络中任意两机器间都可以传输文件,则在一行中输出“The network is connected.”,否则输出“There are kcomponents.”,其中k是网络中连通集的个数。两组测试数据之间请输出一空行分隔。


最简单的数据结构作业了,就是一道acm题,也不用什么乱七八糟的话,仅仅百行以内的代码就搞定。

跟题目一个样子就是一道并查集的问题:

把两种典型的并查集问题联系到了一起:1、查询两个是否是连通的。2、看总共有几个连通区,跟畅通工程是一样的问题。

再注意一些细节的输入输出的处理即可:

自己还编了一组测试数据,进行测试:

还有用了路径压缩的优化方法微笑

#include <iostream>
#include <stdio.h>
using namespace std;
#define maxn 10002///N(≤10000)
int set[maxn];///设置操作数组
int rank[maxn];///按秩压缩的秩数
void init(int n)
{
    for(int i=1;i<=n;i++)
    {
        set[i]=i;///初始化,把父节点都设为自己本身
        rank[i]=1;///设秩的初值
    }
}
int find(int x)///带路径压缩的向上查找
{
    if(set[x]==x)
        return  x;
    return set[x]=find(set[x]);
}
void union_set(int a,int b)///合并,当执行I操作即把两台电脑连接在一起的时候,将父节点设在一起即可
{
    int ta=find(a);
    int tb=find(b);
    if(ta==tb)
        return ;
    if(ta!=tb)
        set[ta]=set[tb];
}
int main()
{
    int n;
    char c;
    int a,b;
    while(~scanf("%d",&n),n){///当读到0的时候,所有操作结束
        init(n);///对一组操作数,先初始化
        while(1)
        {
            scanf("%c",&c);///输入操作符
            if(c=='C'){///C操作表示查询两台电脑是否相连
                scanf(" C%d C%d",&a,&b);///读数据的操作处理不是特别好
                if(find(a)==find(b))///相连“yes”
                    printf("yes\n");
                else
                    printf("no\n");
            }
            if(c=='I')///I操作表示将两台电脑,连接在一起
            {
                scanf(" C%d C%d",&a,&b);
                union_set(a,b);///使用union连接操作
            }
            if(c=='S')///S操作,查询整个网络连通情况。并且表示该组数据全部结束
            {
                int tmp=0;///用来标记有几个连通区
                for(int i=1;i<=n;i++)
                {
                    if(set[i]==i)
                        tmp++;
                }
                if(tmp==1)///只有一个连通区的时候,表示全部连接
                    printf("The network is connected.\n");
                else///否则要输出有多少个并且输出个数
                    printf("There are %d components.\n",tmp);
                break;
            }
        }
    }
    return 0;
}
/**测试数据
输入:
5
I C1 C2
I C2 C3
C C1 C3
C C2 C4
S
10
I C3 C4
I C4 C5
I C6 C7
I C8 C9
I C7 C9
C C6 C8
C C3 C5
C C1 C10
S
3
I C1 C2
I C2 C3
S
0
输出
yes
no
There are 3 components.
yes
yes
no
There are 5 components.
The network is connected.
**/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值