原题传送门
看到题目比较兴奋,无线传感网和我本科的研究方向很重叠,看完题发现题目在骗我。
题目大意
一个无线传感网质量不好完蛋了,他有 n n n台机器,每个机器的覆盖范围为 d d d,覆盖范围内都可以直接通信,也可以进行传递通信,现在要一个一个进行修复,然后输入 O k 1 O \; k_1 Ok1表示修复 k 1 k_1 k1号电脑(当然1<= k 1 k_1 k1<= n n n);输入 S S S k 1 k_1 k1 k 2 k_2 k2询问 k 1 k_1 k1 k 2 k_2 k2号电脑能否连接;
拿到题很熟悉的并查集模型,先输入让你union,然后询问让你find。唯一特殊的地方在于每个base有距离的限制,这是我们采用一个数组用来记录已经repair的机器,再repair的时候比较他和所有已经repair机器的距离,如果小于 d d d,那么就将两个集合union
详细代码
#include<iostream>
#include<queue>
#include<vector>
#include<map>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll int
#define Max 1005
#define p pair<ll,ll>
#define inf 99999999
struct node {
double x, y;
bool operator<(node n) {
if (x == n.x) return y < n.y;
return x < n.x;
}
}arr[Max];
ll n, d, re[Max], cnt = 0, kind[Max];//最后一个数组记录已经修复的计算机
double dis(ll n1, ll n2) {
return sqrt((arr[n1].x - arr[n2].x)*(arr[n1].x - arr[n2].x) + (arr[n1].y - arr[n2].y)*(arr[n1].y - arr[n2].y));
}
ll find(ll a) {
if (kind[a] == a) return a;
else return kind[a] = find(kind[a]);
}
void unions(ll a, ll b) {
ll xx = find(a), yy = find(b);
kind[yy] = xx;//双根合并,天下无敌
}
int main() {
cin >> n >> d;
for (ll i = 1; i <= n; i++) { cin >> arr[i].x >> arr[i].y; kind[i] = i; }
char s;
while (cin >> s) {
ll t, t1; cin >> t;//修复了t
if (s == 'O') {
re[cnt++] = t;
for (ll j = 0; j < cnt; j++) {//和每个已经修复的计算机进行比较
if (dis(t, re[j]) <= d) {//t和某个已经修复的计算机的距离小于d
unions(t, re[j]);
}
}
}
if (s == 'S') {
cin >> t1;
if (find(t) == find(t1)) cout << "SUCCESS" << endl;
else cout << "FAIL" << endl;
}
}
}