2236:Wireless Network
keyword
Union-FInd C++
概要
2次元平面上の点がN(<1000)個与えられる。どの点も最初はinvalidな状態である。validな2点は距離がd以下であるとき隣接する。ある点がvalidになったという情報と、点i,jが連結しているかどうかを尋ねるクエリが与えられる。クエリに対してyesかnoを出力する問題。
UnionFindでくっつけていくだけ。ちょっと無駄が多い感じはする。
int p[1002]; int getRoot(int x){ if(x==p[x]) return x; return p[x] = getRoot(p[x]); } bool isSame(int x, int y){ return getRoot(x) == getRoot(y); } void merge(int x, int y){ p[getRoot(x)] = getRoot(y); } inline int sq(int x){ return x*x;} inline int getDist(int x1, int y1, int x2, int y2){ return sq(x1-x2) + sq(y1-y2); } int main(){ int n, d, i, j, pos, tar, x, y; char c; char line[20]; int xs[1002], ys[1002], adj[1002][1002]; scanf("%d%d\n",&n,&d); d = d*d; REPONE(i,n){ scanf("%d%d\n",xs+i,ys+i); } REPONE(i,n) p[i] = 0; REPONE(i,n){ pos = 0; REPONE(j,n)if(i!=j && d >= getDist(xs[i],ys[i],xs[j],ys[j])){ adj[i][pos++] = j; } adj[i][pos] = 0; } while(scanf("%c",&c)!=EOF){ if(c=='O'){ scanf("%d\n",&tar); p[tar] = tar; for(i=0;adj[tar][i];i++)if(p[adj[tar][i]]) merge(adj[tar][i],tar); } else{ scanf("%d%d\n",&x,&y); if(p[x] && p[y] && isSame(x,y)) printf("SUCCESS\n"); else printf("FAIL\n"); } } return 0; }