由于查询次数可能很多,相互关联的电脑也可能很多,而各个电脑之间的关系只有合并关系和查询,符合并查集的特点。
并查集更偏模板一点,没有什么思维难度,只要把握好需要使用并查集的条件就好了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<map> using namespace std; int n,d,vis[1111],rankk[1010],par[1020]; struct point { int x,y; point(int x = 0,int y = 0) : x(x),y(y) {} bool operator < (const point& r) const { return x<r.x || x==r.x && y<r.y; } } a[1111]; void init(int n) { for(int i=1;i<=n;i++) { par[i] = i; rankk[i] = 0; } } int findd(int x) { return par[x]==x ? x : par[x] = findd(par[x]); } void unite(int x,int y) { x = findd(x); y = findd(y); if(x==y) return ; if(rankk[x]<rankk[y]) { par[x] = y; } else { par[y] = x; if(rankk[x] == rankk[y]) rankk[x]++; } } bool same(int x,int y) { return findd(x) == findd(y); } int main() { memset(vis,0,sizeof(vis)); scanf("%d%d",&n,&d); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].x,&a[i].y); } char s[10]; init(n); int b,c; while(scanf("%s",s)!=EOF) { if(s[0]=='O') { scanf("%d",&b); vis[b] = 1; for(int i=1;i<=n;i++) { if(vis[i]&&i!=b) { int dd = (a[i].x-a[b].x)*(a[i].x-a[b].x)+(a[i].y-a[b].y)*(a[i].y-a[b].y); if(dd<=(d*d)) unite(b,i); } } } else { scanf("%d%d",&b,&c); if(same(b,c)) printf("SUCCESS\n"); else printf("FAIL\n"); } } return 0; }
时间: 2024-10-02 20:48:58