poj 2236 Wireless Network 并查集
题目大意:有n台电脑,并给出每台电脑的坐标,给出距离d意为距离小于等于d的电脑之间才可以联系,且如果A-B,B-C可联系,则A-C也可以联系。输入一系列命令 O代表修复某天电脑,S代表查询某两台电脑是否可以联系。
题目思路:利用并查集将能联系的电脑划分到一个集合内,如果两点的根节点相同则可以联系,属于比较简单的并查集吧。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> #define INF 0x3f3f3f3f #define MAX 1000005 using namespace std; int father[MAX],x[MAX],y[MAX],v[MAX]; double Dist(int a,int b)//计算两点间距离 { double k1=(x[a]-x[b])*(x[a]-x[b])*1.0; double k2=(y[a]-y[b])*(y[a]-y[b])*1.0; return sqrt(k1+k2); } int Find(int x) { while(father[x]!=x) { x=father[x]; } return x; } int main() { int n,i,j,k,a,b,X,Y; char op[5];//为了避免不必要的麻烦用“%s”读入命令 double dist,d; while(scanf("%d%lf",&n,&d)!=EOF) { memset(v,0,sizeof(v)); for(i=1;i<=n;i++) father[i]=i; for(i=1;i<=n;i++) { scanf("%d%d",&x[i],&y[i]); } while(scanf("%s",&op)!=EOF) { if(op[0]=='O')//更新 { scanf("%d",&k); v[k]=1; for(i=1;i<=n;i++) { if(v[i]) { dist=Dist(k,i); if(dist <= d) { X=Find(k); Y=Find(i); if(X!=Y) { father[X]=Y; } } } } } else { scanf("%d%d",&a,&b); if(!v[a] || !v[b])//如果存在未修复的点则失败 { printf("FAIL\n"); continue; } X=Find(a); Y=Find(b); if(X!=Y) { printf("FAIL\n"); } else { printf("SUCCESS\n"); } } } } return 0; }