通信系统

该博客讨论了一个通信系统的设计问题,其中消息需要在各个端点间传递且每个端点只接收一次消息。作者提出了利用无向图和并查集数据结构来判断系统是否满足条件。通过分析题面,作者解释了如何通过并查集来解决这个问题,并提供了代码实现,但遇到了只有50分的情况,寻求帮助改正错误。
摘要由CSDN通过智能技术生成

Codeup有题面的说

某市计划建设一个通信系统。按照规划,这个系统包含若干端点,这些端点由通信线缆链接。消息可以在任何一个端点产生,并且只能通过线缆传送。每个端点接收消息后会将消息传送到与其相连的端点,除了那个消息发送过来的端点。如果某个端点是产生消息的端点,那么消息将被传送到与其相连的每一个端点。
为了提高传送效率和节约资源,要求当消息在某个端点生成后,其余各个端点均能接收到消息,并且每个端点均不会重复收到消息。
现给你通信系统的描述,你能判断此系统是否符合以上要求吗?

让我们康康题面先
题目大意:几个互相连接的端点,求能否达成两个条件----是否每个端点都可以接受到信息和是否都只接收了一次。
结点加相连的路径,自然而然的就想到了图和树这类数据结构吧
两个端点之间的路径是双向的,也就是说可以互相传输,有没有人想到了无向图?
但是貌似不是哦~
我们来看看这个条件:

并且每个端点均不会重复收到消息

因为是双向的路径,所以说,要想只被传输一次,那它最多和两个结点相连(一个传给它,另外一个被它传输,因为不能将信息传回上一个端点,所以还是只接收了一次),或者只与一个相连…

呃…

好像和树形结构有这么一丝丝相似?
再研究一下题面:
输入端点和路径----将端点连接到一起----将端点合到一起
是否有未接收和重复接收的端点----寻找是否有环和不止一个集合----找是否满足条件
最后,所有的端点应该在同一棵树,也就是同一个合中

并 查 集!

ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh有思路了当然就没问题了,几乎是并查集的模板题,对于每个新加入的端点,先判断两个端点是否在同一集合,如果在,连接这两个点必定会形成环,直接输出“No”,如果不在,就将其并为一个集合,随便判断一下这个集合是否有n个端点就OK啦!

上代码(加了几个特判应该不难理解,就不讲了(才不是懒!/拍桌)):

#include <bits/stdc++.h>
using namespace std;
int f[1001] , tj[1001];
int m , n , a , b , hh;
int ff(int x) {
	if (f[x] == x) {
		return x;
	} else {
		x = f[x];
		return ff(x);
	}
}
int main() {
	cin >> n >> m;
	while(m != 0 && n != 0) {
		hh = 0;
		for (int i = 1;i <= n;i++) {
			f[i] = i;
		}
		memset(tj , 0 , sizeof(tj));
		cin >> a >> b;
		f[b] = a;
		for (int i = 1;i <= m - 1;i++) {
			cin >> a >> b;
			tj[a] = 1;
			tj[b] = 1;
			if (ff(a) == ff(b)) {
				cout << "NO" << 1 << endl;
				hh = 1;
			} else {
				f[a] = ff(b);
			}
		}
		if (hh == 0) {
			for (int i = 1;i <= n;i++) {
				if (tj[i] == 0) {
					hh = 1;
					cout << "NO" << 2 << endl;
				}
			}
			if (hh == 0) {
				cout << "YES" << endl;
			}
		}
		cin >> n >> m;
	}
	return 0;
}

但是不知道为什么只有50分,看了看其他dalao的代码发现思路和代码的实现都是差不多的,但是ta却是100分/问号脸

那个dalao的代码也放上来吧,不知道有没有人帮我康康,


#include<iostream>
using namespace std;//题意:①无环 ②连通
int f[1050];
int seek(int x) {
	if (f[x] == x) return x;
	else {
		int FX = seek(f[x]);
		f[x] = FX;
		return FX;
	}
}
int main() {
	int n, m, a, b;
	while (cin >> n >> m) {
		if (n == 0) break;
		bool flag = true;
		for (int i = 1; i <= n; i++) f[i] = i;
		while (m--) {
			cin >> a >> b;
			int FA = seek(a), FB = seek(b);
			if (FA != FB) f[FB] = FA;
			else flag = false;//有环
		}
		for (int i = 1; i < n; i++) {
			if (f[i] != f[i + 1]) flag = false;//不连通
		}
		if (flag) cout << "Yes" << endl;
		else cout << "No" << endl;
	}
	return 0;
}
————————————————
版权声明:本文为CSDN博主「晨子衿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36502291/java/article/details/88582918

求改错!QAQ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值