并查集——POJ-2236

题目含义

给出一堆坏的电脑的坐标和一系列操作

好的电脑如果距离小于等于d可以看做一个集合

然后O是修电脑,S是询问两个电脑在不在一个集合

题目分析

明显的并查集问题,只是要标识好的和坏的电脑,然后只能在好的电脑用并查集

注意:如果让【新修好的电脑】的父亲指向【之前修好的电脑】的话

可能会出错,本该在一个集合的电脑在不同集合了

这样的话,就把【之前修好的电脑】的父亲指向【新修好的电脑】这样就不会出错了

题目代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=1007;
int n,d,p,q,repair[maxn],f[maxn];
char s[2];
struct node{
    int x,y,ok;
}com[maxn];
int dis(node a,node b){
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int get(int x){
    if(f[x]==x)return x;
    else return f[x]=get(f[x]);
}
int main(){
    scanf("%d%d",&n,&d),d=d*d;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&com[i].x,&com[i].y);
        com[i].ok=0;
        f[i]=i;
    }
    int cnt=0;
    while(~scanf("%s%d",&s,&p)){
        if(s[0]=='O'){
            com[p].ok=1;
            repair[cnt++]=p;
            for(int i=0;i<cnt-1;i++){
                int fx=get(repair[i]),fy=get(p);
                if(dis(com[p],com[repair[i]])<=d)
                    f[fx]=fy;
            }
        }
        else if(s[0]=='S'){
            scanf("%d",&q);
            int fx=get(p),fy=get(q);
            if(fx==fy&&com[p].ok&&com[q].ok)printf("SUCCESS\n");
            else printf("FAIL\n");
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/helman/p/11234278.html