【题目大意】
已知每一台电脑只能与它距离为d的电脑相连通,但是两台电脑间可以以第三台作为媒介连接。现在电脑全被损坏。每次可以进行两个操作中的一个,或是修好一台电脑,或是查询两台电脑是否连通。
【思路】
显然是并查集。每次修好一台新电脑,就与之前修好的每一台电脑进行判断,距离在d以内就合并。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int MAXN=1001+50; 6 int n,d; 7 int x[MAXN],y[MAXN],rep[MAXN]; 8 int h[MAXN],pa[MAXN]; 9 10 int ind(int a,int b) 11 { 12 return ((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])<=d*d); 13 } 14 15 void newset() 16 { 17 for (int i=0;i<n;i++) 18 { 19 h[i]=0; 20 pa[i]=i; 21 } 22 } 23 24 int find(int x) 25 { 26 int r=x; 27 while (pa[r]!=r) r=pa[r]; 28 int p=x; 29 while (pa[p]!=r) 30 { 31 int temp=pa[p]; 32 pa[p]=r; 33 p=temp; 34 } 35 return r; 36 } 37 38 void unionset(int fa,int fb) 39 { 40 if (h[fa]>=h[fb]) 41 { 42 pa[fb]=fa; 43 if (h[fa]==h[fb]) h[fa]++; 44 } 45 else 46 pa[fa]=fb; 47 } 48 49 int main() 50 { 51 scanf("%d%d",&n,&d); 52 for (int i=0;i<n;i++) 53 { 54 scanf("%d%d",&x[i],&y[i]); 55 } 56 57 char c; 58 int repd=0;//ÒѾÐ޺õĵçÄÔÊýÁ¿ 59 newset(); 60 61 getchar(); 62 while (scanf("%c",&c)!=EOF) 63 { 64 if (c==‘S‘) 65 { 66 int a,b; 67 scanf("%d%d",&a,&b); 68 a--; 69 b--; 70 if (find(a)==find(b)) cout<<"SUCCESS"<<endl;else cout<<"FAIL"<<endl; 71 } 72 73 else 74 { 75 int a; 76 scanf("%d",&a); 77 a--; 78 for (int i=0;i<repd;i++) 79 { 80 if (ind(a,rep[i])) 81 { 82 int fa=find(a),fb=find(rep[i]); 83 unionset(fa,fb); 84 } 85 } 86 rep[repd]=a; 87 repd++; 88 } 89 getchar(); 90 } 91 return 0; 92 }
时间: 2024-10-06 05:16:38