题目链接:http://poj.org/problem?id=2236
题目大意:城市网络由n台电脑组成,因地震全部瘫痪,现在进行修复,规定距离小于等于d的电脑修复之后是可以直接相连
进行若干操作,O a,修复编号为a的电脑,S a,b 询问a,b电脑能否联系
思路分析:并查集,只是和并条件变了,首先要已经被修复(vis数组)其次距离要小于d,并查集搞完之后
询问的时候只需要看他们是不是有着相同的根节点即可。
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int maxn=1000+10; struct node { double x; double y; }; node com[maxn]; int fa[maxn]; bool vis[maxn]; int n,d; double dis(int i,int j) { return sqrt((com[i].x-com[j].x)*(com[i].x-com[j].x)+(com[i].y-com[j].y)*(com[i].y-com[j].y)); } int root(int x) { return (x==fa[x])?x:fa[x]=root(fa[x]); } void merge(int x,int y) { int fx=root(x); int fy=root(y); if(fx==fy) return; fa[fx]=fy; } int main() { char s[10]; int a,b; memset(vis,false,sizeof(vis)); scanf("%d%d",&n,&d); for(int i=1;i<=n;i++) { scanf("%lf%lf",&com[i].x,&com[i].y); fa[i]=i; } while(scanf("%s",s)!=EOF) { if(s[0]=='O') { scanf("%d",&a); vis[a]=true; for(int i=1;i<=n;i++) { if(dis(a,i)<=d&&vis[i]) merge(i,a); } } if(s[0]=='S') { scanf("%d%d",&a,&b); if(root(a)==root(b)) printf("SUCCESS "); else printf("FAIL "); } } }