题目链接:http://poj.org/problem?id=2236
题意:给你n台计算机的坐标。d是可通信的最大距离。有两个操作。
1、O p 表示修复计算机p.
2、S p q表示询问pq是否能够通信。
题解:并查集的提升。把距离考虑在判断内。如果修复了p就对当前集合做一个并操作。查找的时候直接判断父亲是不是共同的即可。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <algorithm> 6 #include <cmath> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #define ll long long 11 using namespace std; 12 const int maxn = 1010; 13 14 int dx[maxn],dy[maxn]; 15 int f[maxn],vis[maxn]; 16 int n,d; 17 18 int dis(int a,int b){ 19 int distance = (dx[a]-dx[b]) * (dx[a] - dx[b]) + (dy[a]-dy[b]) * (dy[a] - dy[b]); 20 if(distance <= d*d) return true; 21 else return false; 22 } 23 24 void init(int n){ 25 for(int i = 0 ; i <= n; i++) 26 f[i] = i,vis[i] = 0; 27 } 28 29 int find(int x){ 30 if(x == f[x]) 31 return x; 32 return f[x] = find(f[x]); 33 } 34 35 void join(int a, int b){ 36 a = find(a); 37 b = find(b); 38 if(a != b){ 39 f[a] = b; 40 } 41 } 42 43 int main(){ 44 45 cin>>n>>d; 46 for(int i = 0; i < n ;i++){ 47 cin>>dx[i]>>dy[i]; 48 } 49 50 init(n); 51 char ch; 52 int num; 53 int cnt = 0; 54 while(cin>>ch){ 55 if(ch == 'O'){ 56 cin>>num; 57 num--; 58 vis[cnt++] = num; 59 for(int i = 0; i < cnt-1; i++){ 60 if(vis[i] != num && dis(vis[i],num)){ 61 join(vis[i],num); 62 } 63 } 64 } 65 else{ 66 int p,q; 67 cin>>p>>q; 68 if(find(p-1) == find(q-1)){ 69 cout<<"SUCCESS"<<endl; 70 } 71 else{ 72 cout<<"FAIL"<<endl; 73 } 74 } 75 } 76 return 0; 77 }