poj2236 Wireless Network(并查集直接套模板
题目地址:http://poj.org/problem?id=2236
题目大意:n台电脑都坏了,只有距离小于d且被修好的电脑才可以互相联系,联系可传递。输入n和d,n个点的坐标x y。两个操作:O x表示把电脑x修好了,S x y表示询问x和y能否联系。
思路:并查集把能互相联系的电脑都放到同一个集合里(联系可以互相传递),查询的时候只要看x和y是否在一个集合就行了。
另设置两个数组visit[x]表示x是否被修好,dis[x][y]表示x和y之间的距离是否符合要求【先预处理任意两个点之间的距离<=d的标记为1】。
每修好一台电脑记得改变visit标记且把所有和他能联系的电脑合并(距离合适且修好了)。
1 #include <cstdio> 2 3 using namespace std; 4 5 const int maxn = 1010; 6 int fa[maxn], visit[maxn], dis[maxn][maxn]; 7 8 struct node 9 { 10 int x, y; 11 }node[maxn]; 12 13 //先预处理所有点间的距离 14 void pre(int n, int d) 15 { 16 for(int i = 1; i <= n; i++) 17 for(int j = 1; j <= n; j++) 18 { 19 int dx = node[i].x - node[j].x; 20 int dy = node[i].y - node[j].y; 21 if(dx*dx + dy*dy <= d*d) 22 dis[i][j] = 1; 23 else 24 dis[i][j] = 0; 25 } 26 } 27 28 void init(int n) 29 { 30 for(int i = 1; i <= n; i++) 31 { 32 fa[i] = i; 33 visit[i] = 0; 34 } 35 } 36 37 int found(int x) 38 { 39 if(fa[x] == x) 40 return x; 41 return fa[x] = found(fa[x]); 42 } 43 44 void unite(int x, int y) 45 { 46 int px = found(x); 47 int py = found(y); 48 if(px == py) 49 return; 50 else 51 fa[px] = py; 52 } 53 54 int main() 55 { 56 int n, d, x, y; 57 char opr; 58 scanf("%d%d", &n, &d); 59 init(n); 60 for(int i = 1; i <= n; i++) 61 scanf("%d%d", &node[i].x, &node[i].y); 62 pre(n, d);//pre要写在输入坐标之后!!!!不然dis就全是1!!! 63 getchar(); 64 while(scanf("%c", &opr) == 1) 65 { 66 if(opr == 'O') 67 { 68 scanf("%d", &x); 69 visit[x] = 1; 70 for(int i = 1; i <= n; i++) 71 if(visit[i] && dis[x][i])//距离合适且修好了的就可以互相联络 72 unite(x, i);//能互相联络的都放一个集合里 73 } 74 else 75 { 76 scanf("%d%d", &x, &y); 77 if(found(x) == found(y)) 78 printf("SUCCESS\n"); 79 else 80 printf("FAIL\n"); 81 } 82 getchar(); 83 } 84 return 0; 85 }
【pre(n, d)要放到输入坐标之后!!!!!!因为要用到坐标!!!!!!!!不然dis全是1!!!!!!!!!!!!!!!!!!!!!!!】