NOIP 2017 Day2 题1:奶酪 并查集

NOIP 2017 Day2 题1:奶酪 并查集 洛谷上全部通过


#include <bits/stdc++.h>

using namespace std;

const  int MAX_N=1002;
int father[MAX_N];
int ran[MAX_N];

double x[1002];
double y[1002];
double z[1002];

void init(int n){
      memset(father,-1,sizeof(father));
      for(int i=0;i<=n;i++){
            father[i]=i;
            ran[i] = 0;
      }

}

int find(int x){
   if( father[x]==x ) {
      return x;
   }
   else{
      int t = father[x];
      return  father[x] = find(t);

   }

}

bool same(int x ,int y){
      return (   find(x)== find(y));

}

double  dist(int dong1,int dong2){

                  //刚开始 x,y, 坐标设为int ,结果溢出来了
                 return(   sqrt(  ( x[dong1]-x[dong2] ) *(  x[dong1]-x[dong2] )
                                + ( y[dong1]-y[dong2] ) *(  y[dong1]-y[dong2] )
                                + ( z[dong1]-z[dong2] ) *(  z[dong1]-z[dong2] )       )   );

}

void unite(int x,int y){
      int f1 = find(x);
      int f2 = find(y);

      if(f1!=f2){

            if( ran[f1] < ran[f2]) {
                   father[f1]= f2 ;
             }
            else{
                  father[f2]= f1;
                  if( ran[f1] == ran[f2] ) ran[f1] ++; //ÕâÀïдµÄ²»´í
            }
      }
}



int main()
{

      int T;
      cin >> T;
      for(int t=1;t<=T;t++){
            int n,h,r;
            cin >> n  >>h >> r;

            init(n+1);

            for(int i=1;i<=n;i++){
                  cin >> x[i] >> y[i] >>z[i];
            }


             for(int i=1;i<=n;i++){

                 if( z[i]<=r  ){      unite( i , 0 );  }
                 if( z[i]>=h-r )  unite( i , n+1 );

            }


             for(int i=1;i<=n;i++){
                        for(int j=i+1;j<=n;j++){
                              //cout <<  dist(i,j);
                             // cout <<  2* r;
                              if(  dist(i,j)<=2*r ) unite(i,j);

                        }
            }

            if( same(0,n+1)) cout << "Yes"<<endl;
            else  cout <<  "No" <<endl;
      }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值