题目来源:poj 2236 Wireless Network
注意:
在合并时,我们只需要考虑这台电脑与之前已经修复的电脑能够通讯。设置一个vis数组。
#include <iostream>
using namespace std;
const int maxn = 1010;
int father[maxn]; //父亲数组
int height[maxn]; //树的高度
int N, d;
typedef pair<int, int> pii;
pii a[maxn];
bool vis[maxn];
//初始化N个元素
void init()
{
for (int i = 1; i <= N; i++)
{
father[i] = i; //令father[i]=-1也可以
vis[i] = false;
height[i] = 0;
}
}
//查找树的根
int find(int x)
{
if (father[x] == x)
{
return x;
}
else
{
return find(father[x]);
}
}
//合并x和y所属的集合
void unite(int x, int y)
{
int faX = find(x);
int faY = find(y);
if (faX == faY)
{
return;
}
if (height[faX] < height[faY])
{
father[faX] = faY;
}
else
{
father[faY] = faX;
if (height[faX] == height[faY])
{
height[faX]++;
}
}
}
//判断x和y是否属于同一个集合
bool same(int x, int y)
{
return find(x) == find(y);
}
int dis(int i, int j)
{
return (int)(a[i].first - a[j].first) * (a[i].first - a[j].first) + (a[i].second - a[j].second) * (a[i].second - a[j].second);
}
int main()
{
while (scanf("%d%d", &N, &d) == 2)
{
init();
int x, y;
for (int i = 1; i <= N; i++)
{
cin >> x >> y;
a[i] = make_pair(x, y);
}
char ope[3];
while (~scanf("%s", ope))
{
if (ope[0] == 'O')
{
int id;
cin >> id;
vis[id] = true;
for (int i = 1; i <= N; i++)
{
if (vis[i] && dis(i, id) <= d * d)
{
unite(i, id);
}
}
}
else if (ope[0] == 'S')
{
int x, y;
cin >> x >> y;
if (find(x) == find(y))
{
cout << "SUCCESS" << endl;
}
else
{
cout << "FAIL" << endl;
}
}
}
}
return 0;
}