/**
题意:输入n,d;
输入n行代表有n个机器及它们的坐标,;
d代表两两间电脑的距离如果小于d的话就可以代表它们之间可以联系;
输入字符'O'和P的话,就是说将P号电脑进行修理,满足条件的可以进行连通(联系);
输入字符'S'和P,Q的话呢,就是判断P和Q是否连通;
这个题吧,就是按照所给的意思一步一步搞就可以了,需要解决什么就弄吧;
判连通性那么就是并查集了,而且这个题开始的地方呢,我感觉诡异的地方呢就是它的这个输入有点坑;
后来也就慢慢理解了;
*/
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e3+7;
int n,pre[maxn],d,x[maxn],y[maxn];
bool vis[maxn];
int Find(int root)
{
int son=root;
while(root!=pre[root]) root=pre[root];
/**
下面是路径压缩,这个真的很有必要,有喝没有差别将近1000ms;
当然这个题目我还是跑了很久的(3250ms) ,有的大佬跑出了79ms,不知道怎么做的,伏地膜大佬。
*/
while(son!=root)
{
int temp=pre[son];
pre[son]=root;
son=temp;
}
return root;
}
void join(int root1,int root2)
{
int x=Find(root1),y=Find(root2);
if(x!=y) pre[x]=y;
}
bool dis(int a,int b)
{
int k1=x[a]-x[b],k2=y[a]-y[b];
if(k1*k1+k2*k2<=d*d) return true;
return false;
}
int main ()
{
scanf("%d %d",&n,&d);
for(int i=1;i<=n;i++)
{
vis[i]=false;
pre[i]=i;
}
for(int i=1;i<=n;i++)
scanf("%d %d",&x[i],&y[i]);
char ch;
while(~scanf("%c",&ch))
{
if(ch=='O')
{
int P;
scanf("%d",&P);
vis[P]=true;
for(int i=1;i<=n;i++)
if(dis(i,P)&&vis[i]&&i!=P) join(i,P);///满足条件两两进行合并;
}
else if(ch=='S')
{
int P,Q;
scanf("%d %d",&P,&Q);
int x=Find(P);
int y=Find(Q);///判连通性;
if(x==y) printf("SUCCESS\n");
else printf("FAIL\n");
}
}
return 0;
}
Wireless Network POJ - 2236 并查集判连通性
最新推荐文章于 2021-09-13 20:57:53 发布