题目大意:
地震啦,电脑的通信坏了,但是正在修理 —— 输入 “ O 1”,表示1号电脑被修好了 ,输入“ S 1 2 ” 表示询问这两台电脑能不能通讯。规定两台电脑之间的距离小于等于d的时候才能通讯,如果A,B能通讯,B能跟C通讯,那么A也能跟C通讯。第一行输入N, d,N表示有几台电脑,d表示最长距离。接下来N行,第i行表示第i台电脑的坐标。接下来输入操作。询问的时候输出“SUCCESS”或者“FAIL”。(输入行数不超过三万行)
参考思路:
自己的: 输入一个修理成功的电脑,把他存起来,和前面那些已经修好的电脑判断一下,判断条件是:1、已经修好的;2、距离小的。连接过了之后碰到询问的时候,就看看这两个点的根结点是不是一样。
参考代码:
1 #include <iostream> 2 #include <vector> 3 #include <map> 4 #include <string> 5 #include <queue> 6 #include <stack> 7 #include <set> 8 9 #include <cstdio> 10 #include <cstring> 11 #include <cmath> 12 #include <cstdlib> 13 using namespace std; 14 15 const int INF=0x3f3f3f3f; 16 const int SIZE=1e3+10; 17 18 struct node{ 19 int id; 20 int fix; ///是否被修好? 21 double x,y; 22 }cmt[SIZE] ; 23 24 int sz[SIZE]; 25 int n; 26 double d; 27 ///要把电脑连接起来。 28 29 double dis(int p,int q) 30 { 31 double temp=(cmt[p].x-cmt[q].x)*(cmt[p].x-cmt[q].x)+(cmt[p].y-cmt[q].y)*(cmt[p].y-cmt[q].y); ///距离 32 33 return temp; 34 } 35 int find(int x) 36 { 37 while(cmt[x].id!=x) 38 { 39 cmt[x].id=cmt[cmt[x].id].id; 40 x=cmt[x].id; 41 } 42 return x; ///寻找根节点 43 } 44 bool connect(int p,int q) 45 { 46 return find(p)==find(q); 47 } 48 49 void un(int p,int q) 50 { 51 52 if(cmt[q].fix==0||dis(p,q)>d*d) return; ///没修过?距离太大? 53 int pr=find(p); 54 int qr=find(q); 55 56 if(pr==qr) return ; ///根节点已经相同 57 if(sz[pr]<sz[qr]) {sz[qr]+=sz[pr];cmt[pr].id=qr;} 58 else {sz[pr]+=sz[qr];cmt[qr].id=pr;}//cout<<"UN:"<<cmt[]<<" "<<sz[q]<<endl; 59 } 60 61 void clear() 62 { 63 for(int i=1;i<=n;i++) 64 sz[i]=1; 65 } 66 67 int main() 68 { 69 int i,j; 70 cin>>n>>d; 71 clear(); 72 for(i=1;i<=n;i++) 73 { 74 cin>>cmt[i].x>>cmt[i].y; 75 cmt[i].fix=0; 76 cmt[i].id=i; 77 } 78 char x; 79 int temp,a,b; 80 while(cin>>x) 81 { 82 if(x=='O') 83 { 84 cin>>temp; 85 cmt[temp].fix=1; ///修过啦 86 for(i=1;i<=n;i++) 87 if(i!=temp) 88 un(temp,i); 89 } 90 else 91 { 92 cin>>a>>b; 93 if(!connect(a,b)) cout<<"FAIL "; 94 else cout<<"SUCCESS "; 95 } 96 } 97 return 0; 98 } 99 100 ///http://blog.csdn.net/dm_vincent/article/details/7655764 (并查集相关) 101