某市计划建设一个通信系统。按照规划,这个系统包含若干端点,这些端点由通信线缆链接。消息可以在任何一个端点产生,并且只能通过线缆传送。每个端点接收消息后会将消息传送到与其相连的端点,除了那个消息发送过来的端点。如果某个端点是产生消息的端点,那么消息将被传送到与其相连的每一个端点。
为了提高传送效率和节约资源,要求当消息在某个端点生成后,其余各个端点均能接收到消息,并且每个端点均不会重复收到消息。
现给你通信系统的描述,你能判断此系统是否符合以上要求吗?
让我们康康题面先
题目大意:几个互相连接的端点,求能否达成两个条件----是否每个端点都可以接受到信息和是否都只接收了一次。
结点加相连的路径,自然而然的就想到了图和树这类数据结构吧
两个端点之间的路径是双向的,也就是说可以互相传输,有没有人想到了无向图?
但是貌似不是哦~
我们来看看这个条件:
并且每个端点均不会重复收到消息
因为是双向的路径,所以说,要想只被传输一次,那它最多和两个结点相连(一个传给它,另外一个被它传输,因为不能将信息传回上一个端点,所以还是只接收了一次),或者只与一个相连…
呃…
好像和树形结构有这么一丝丝相似?
再研究一下题面:
输入端点和路径----将端点连接到一起----将端点合并到一起
是否有未接收和重复接收的端点----寻找是否有环和不止一个集合----查找是否满足条件
最后,所有的端点应该在同一棵树,也就是同一个集合中
并 查 集!
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