题意:
修复n台已经被损坏的电脑,两者距离小于d可以直接连接,否则只能通过其他电脑进行连接。
两种操作,O x表示修复第x台电脑,S x y表示判断x y 间是否链接。
题解:
并查集的基础应用:
每次修复,将其加入能够加入的集合。每次判断是否连接,看是否在一个集合内就可以了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<vector>
#include<functional>
#include<utility>
#include<set>
#include<map>
#include<cmath>
#include<stack>using namespace std;const int maxn=1030;int pa[maxn];bool status[maxn];
bool able[maxn][maxn];int findset(int x)
{return pa[x]<0? x: pa[x]=findset(pa[x]);
}pair<int,int>a[maxn];int main()
{int n,d;cin>>n>>d;for(int i=0; i<n; i++)cin>>a[i].first>>a[i].second;memset(pa,-1,sizeof(pa));for(int i=0; i<n; i++){for(int x=i+1; x<n; x++)if((a[x].first-a[i].first)*(a[x].first-a[i].first)+(a[x].second-a[i].second)*(a[x].second-a[i].second)<=d*d){able[x][i]=true;able[i][x]=true;}}char c;int x,y;while(cin>>c){if(c=='O'){scanf("%d",&x);x--;status[x]=true;for(int i=0; i<n; i++){if(x==i)continue;if(status[i]&&able[x][i])if(findset(x)!=findset(i))pa[findset(x)]=findset(i);}}else{scanf("%d%d",&x,&y);x--;y--;if(findset(x)==findset(y))printf("SUCCESS\n");else printf("FAIL\n");}}return 0;
}