题目大意:首先是输入两个整数N和d,N表示电脑数目,d表示两台电脑能够直接连通的最大距离,
接着输入N个坐标,表示每一台电脑的位置。在最开始的时候,所有电脑都是坏的,
输入O p表示维修p电脑,p表示电脑的序号(1~N),
输入S p q表示查询p电脑和q电脑是否连通,若连通,则输出SUCCESS,失败则输出FAIL。
题目链接:http://poj.org/problem?id=2236
解题思路:这是一道使用并查集的简单题目,不熟悉并查集的可以看一下这篇博文:http://blog.csdn.net/dellaserss/article/details/7724401,简单易懂。
最开始的时候所有电脑的根节点都为自己,当维修好一台电脑时,获取与这台电脑距离小于等于d的电脑,若取得的电脑已经维修好,则将该电脑与当前维修的
电脑合并,否则不合并。 查询两台电脑是否连通时,只需要查询两台电脑的根节点是否相同就可以了。
//POJ2236
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 1003;
int par[N];
int book[N];
struct Point
{
int x, y;
}point[N];
int getDis(Point a, Point b)
{
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}
void init(int n)
{
int i;
for(i=1; i<=n; ++i)
{
par[i] = i;
}
}
int find(int x)
{
int r = x;
int tmp;
while(par[r] != r)
{
r = par[r];
}
while(par[x] != r)
{
tmp = par[x];
par[x] = r;
x = tmp;
}
return r;
}
void join(int x, int y)
{
int a = find(x);
int b = find(y);
if(a != b)
{
par[a] = b;
}
}
int main()
{
int n, d;
int i;
char op;
int num, three;
double l;
cin >> n >> d;
init(n);
for(i=1; i<=n; ++i)
{
cin >> point[i].x >> point[i].y;
}
while( cin >> op )
{
if(op == 'O')
{
cin >> num;
book[num] = 1;
for(i=1; i<=n; ++i)
{
l = getDis(point[num], point[i]);
if(l <= d*d && book[i])
{
join(num, i);
}
}
}
else if(op == 'S')
{
cin >> num >> three;
if(find(num) == find(three))
{
cout << "SUCCESS" << endl;
}
else
{
cout << "FAIL" << endl;
}
}
}
return 0;
}