描述
n台电脑,如果两台电脑间的距离的d范围内,则两台电脑能够连通。
如果AB连通,BC连通,则认为AC连通。
已知电脑台数N,最大距离d,以及每个电脑的坐标。有如下两种操作:
O i 表示修复编号为i的电脑
S i j 表示判断电脑ij能否连通。
对每一个S操作,如果电脑ij能连通,输出SUCCESS,否则输出FAIL
思路
典型的并查集。
初始:每个点的父节点都是自身
每修复一个点,让所有能与这个点连通的点的根节点都指向这个点的根节点
每查询两个点,取得它们的根节点,判断是否相同,如果相同,输出SUCCESS,否则,输出FALSE
代码
1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 6 #define MAXN 1002 7 8 int par[MAXN]; 9 int height[MAXN]; 10 bool mode[MAXN]; 11 bool dis[MAXN][MAXN]; 12 13 14 void Init(int n) 15 { 16 for (int i = 0; i < n; i++) 17 { 18 par[i] = i; 19 height[i] = 0; 20 } 21 } 22 23 int find(int x) 24 { 25 if (par[x] == x) 26 return x; 27 else 28 return par[x] = find(par[x]); 29 } 30 31 void unite(int x,int y) 32 { 33 x = find(x); 34 y = find(y); 35 36 if (x!=y) 37 { 38 if (height[x] < height[y]) 39 par[x] = y; 40 else 41 { 42 par[y] = x; 43 if (height[x] == height[y])height[x]++; 44 } 45 } 46 47 } 48 49 bool isSame(int x, int y) 50 { 51 return find(x) == find(y); 52 } 53 54 55 int main() 56 { 57 //freopen("C:\Users\zgwng\Desktop\2236.txt", "r",stdin); 58 59 int n, d; 60 cin >> n >> d; 61 int *x = new int[n]; 62 int *y = new int[n]; 63 64 for (int i = 0; i < n; i++) 65 { 66 cin >> x[i] >> y[i]; 67 mode[i] = false; 68 } 69 70 71 int d2 = d*d; 72 for(int i=0;i<n;i++) 73 for (int j = 0; j < n; j++) 74 { 75 if ((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]) <= d2) 76 dis[i][j] = dis[j][i] = true; 77 else 78 dis[i][j] = dis[j][i] = false; 79 80 } 81 delete[]x; 82 delete[]y; 83 84 Init(n); 85 //开始处理输入操作 86 char oper; 87 while (cin>>oper) 88 { 89 int i, j; 90 if (oper == 'O') 91 { 92 //修复 93 cin >> i; 94 i--; 95 mode[i] = true; 96 for (int k = 0; k < n; k++) 97 { 98 if (dis[i][k] && mode[k]) 99 unite(i, k); 100 } 101 102 }//end if oper==o 103 else 104 { 105 cin >> i >> j; 106 i--; 107 j--; 108 if (isSame(i, j)) 109 cout << "SUCCESS" << endl; 110 else 111 cout << "FAIL" << endl; 112 } 113 } 114 115 return 0; 116 }