Input
The first line contains two integers N and d (1 <= N <= 1001, 0 <= d <= 20000). Here N is the number of computers, which are numbered from 1 to N, and D is the maximum distance two computers can communicate directly. In the next N lines, each contains two integers xi, yi (0 <= xi, yi <= 10000), which is the coordinate of N computers. From the (N+1)-th line to the end of input, there are operations, which are carried out one by one. Each line contains an operation in one of following two formats:
1. "O p" (1 <= p <= N), which means repairing computer p.
2. "S p q" (1 <= p, q <= N), which means testing whether computer p and q can communicate.
output
The input will not exceed 300000 lines.
For each Testing operation, print "SUCCESS" if the two computers can communicate, or "FAIL" if not.
题意:有N台电脑,编号1-n. 然后d为两台电脑之间的最小连接距离:给出当两台电脑坐标距离小于d时,两台电脑可以直接连接。 电脑之间也可以间接连接:例如B-C ,A-B 则可得A-C
然后在N台坐标输入结束后执行操作 O p 激活电脑p,S p q判断p q 是否连接(输入判断不超过300000行)
思路:连接问题可以看做所有连通的元素属于一个集合中。然后就是关于unite(Union)和find函数的修改,写一个判断距离条件的函数,以及如何存储问题:
通过结构体数组来记录下标,在输入结束后开始遍历周围符合条件的坐标点将其关联(即符合距离条件),在进行操作unite时就判断是否符合距离条件以及周围的点是否被激活
完整题解:
#include<iostream> #include<cstdio> #include<cstring> const int maxn = 1005; using namespace std; int pre[maxn],p[maxn][2]; bool dis[maxn][maxn],vis[maxn]; long long getdis(int x1,int y1,int x2,int y2) { //距离公式 return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int find(int x) { if(x!=pre[x]) return pre[x] = find(pre[x]); else return pre[x]; } void unite(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) { pre[fx]=fy; } } bool judge(int x,int y){ if(find(x)==find(y)) return true; else return false; } int main() { int n,d,x,y; char s; memset(vis,false,sizeof(vis)); memset(dis,false,sizeof(dis)); scanf("%d%d",&n,&d); for(int i=0; i<=n; i++) pre[i]=i; for(int i=1; i<=n; i++) { scanf("%d%d",&p[i][0],&p[i][1]); } for(int i=1; i<=n; i++) //把每个点周围都关联起来; { for(int j=i; j<=n; j++) { if(getdis(p[i][0],p[i][1],p[j][0],p[j][1])<=d*d) dis[i][j]=dis[j][i]=true;//先把dis符合条件关联 } } while(cin>>s) { if(s=='O') { scanf("%d",&x); vis[x]=true; for(int i=1; i<=n; i++) { if(i!=x&&vis[i]&&dis[i][x]) { unite(i,x); } } } else { scanf("%d%d",&x,&y); if(judge(x,y)) printf("SUCCESS "); else printf("FAIL "); } } }