您的位置:首页 > 其它

PKU 2236 Wireless Network(并查集)

2009-08-14 21:04 225 查看
http://acm.pku.edu.cn/JudgeOnline/problem?id=2236

题目大意:亚洲海底地震,使得所有的电脑都坏了并中断了联系,现在有一群维修人员被派往现场修复。他们在那边会做两件事,1.“O”代表要修复某编号的电脑,“S”代表要测试两台编号不同的电脑是否可以连通,测试成功,则输出成功,否则失败。但是两台电脑之间如果要直接连通的话,它们之间的距离不能够超过OJ提供的距离D,如果超过的话,他们要连通的话,中间就要有中介电脑才行。现在你的工作就是根据修复人员所做的操作,输出成功或者失败。

解题思路:这道的话就是属于互通的题目啦,也就是要用到并查集。修复一台电脑就标记为修复过了,然后跟其他已经修复过的电脑进行合并,但是合并的条件必须是两台电脑的距离小于D。当要测试两台电脑时,就是判断他们的根结点是否一样或者是距离小于D,然后再进行合并。

#include <iostream>
#include <math.h>
using namespace std;
#define size 1002

int parents[size];
int deep[size];
bool visited[size];

struct coordinate
{
double x;
double y;
}locate[size];

void CreateSet(int x)//创建集合
{
parents[x] = x;
deep[x] = 1;
visited[x] = false;
}

int Find(int x)//寻找根结点
{
int r = x;
int temp;
while(r!=parents[r])
r = parents[r];
while (x!=r)
{
temp = parents[x];
parents[temp] = r;
x = temp;
}
return r;
}

void Union(int a,int b)//合并集合
{
int t1 = Find(a);
int t2 = Find(b);
if(deep[t1]>deep[t2])
parents[t2] = t1;
else
parents[t1] = t2;
if(deep[t1] == deep[t2])
deep[t2]++;
}

bool IsOk(int a,int b,long distance)//判断两台电脑是否可以连通
{
double k;
k = sqrt((locate[a].x-locate[b].x)*(locate[a].x-locate[b].x)+(locate[a].y-locate[b].y)*(locate[a].y-locate[b].y));
if(k<=distance)
return true;
else
return false;
}

int main()
{
char commander;
int computer;
int p1,p2;
int i;
long distance;
cin>>computer>>distance;
for(i=1;i<=computer;i++)
CreateSet(i);
for (i=1;i<=computer;i++)
cin>>locate[i].x>>locate[i].y;
while (cin>>commander)
{
if (commander == 'O')
{
cin>>p1;
visited[p1] = true;
/*查看修复的电脑是否可以加入到并查集中*/
for(i=1;i<=computer;i++)
{
if(visited[i]&&i!=p1)
if(IsOk(p1,i,distance))
if(Find(p1)!=Find(i))
Union(p1,i);
}
}
else
{
cin>>p1>>p2;
if(IsOk(p1,p2,distance)||Find(p1)==Find(p2))
{
cout<<"SUCCESS"<<endl;
if(Find(p1)!=Find(p2))
Union(p1,p2);
}
else
cout<<"FAIL"<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: