学习并查集QAQ,球球大佬orz
/*
1、基层是联通块问题
2、可以运用搜索,此题深搜应该比较合理
3、最近学习并查集ing,所以尝试运用并查集知识
4、检索空洞,将与上层相连的空洞以及与下层相连的空洞存储
5、并查集——并。联通的空洞合并为一个集合
6、并查集——查。查询上层与下层空洞是否有联通的
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#define ll long long
using namespace std;
int t, n, ;
ll h, r;
int upper_index = -1, lower_index = -1;
struct def {
ll x, y, z, fa;
};
def point[1005];
int upper_point[700];
int lower_point[700];
bool is_neighbour(def p, def q) { //判断p,q两点是否相连
ll xx = pow((p.x - q.x), 2);
ll yy = pow((p.y - q.y), 2);
ll zz = pow((p.z - q.z), 2);
ll dis = pow(2 * r, 2);
if (xx + yy + zz >= dis) return true;
else return false;
}
void get_basic_data() {
cin >> n >> h >> r;
for (int i = 0; i < n; ++t) {
cin >> point[i].x >> point[i].y >> point[i].z;
point[i].fa = i;
if (point[i].z + r >= h)upper_point[++upper_index] = i;
else if (point[i].z - r <= 0)lower_point[++lower_index] = i;
}
}
void initialize() {
n = 0; h = 0; r = 0;
memset(upper_point, 0, sizeof(upper_point));
memset(lower_point, 0, sizeof(lower_point));
for (int i = 0; i < n; ++i) {
point[i].x = 0;
point[i].y = 0;
point[i].z = 0;
point[i].fa = 0;
}
upper_index = -1;
lower_index = -1;
}
int get(int x) { //输入点的序号(索引)即可
if (point[x].fa == x)return x;
return point[x].fa = get(point[x].fa);
}
void merge(int x, int y) { //输入点的索引
point[get(x)].fa = get(y);
}
void processing_merge() {
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (is_neighbour(point[i], point[j]))merge(i, j);
}
}
}
bool processing_get() {
for (int i = 0; i < upper_index; ++i) {
for (int j = 0; j < lower_index; ++j) {
if (get(upper_point[i]) == get(lower_point[j]))
return true;
}
}
return false;
}
int main() {
cin >> t;
for (int i = 1; i <= t; ++i) {
initialize();
get_basic_data();
processing_merge();
if (processing_get())cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
各个部分都写成函数了,应该蛮好读懂的,球球了!!