奶酪sol

奶酪

  • 直接用并查集维护连通性
  • 然而我用了连边后bfs,较慢
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(),x.end()
#define U(i,u) for(register int i=head[u];i;i=nxt[i])
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
#define per(i,a,b) for(register int i=(a);i>=(b);--i)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> PII;
typedef vector<int> VI;
template<class T> inline void read(T &x){
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f;
}
template<class T> inline void cmin(T &x, T y){x=x<y?x:y;}
template<class T> inline void cmax(T &x, T y){x=x>y?x:y;}
const int N=2010;
const ld ex=1e-8;
int n,s,t;
ld h,r,x[N],y[N],z[N];
int head[N],nxt[N*N],v[N*N],cnt;
int ge[N];
void add(int a,int b){
	nxt[++cnt]=head[a];head[a]=cnt;v[cnt]=b;
}
ld calc(int i,int j){
	if(i==j)return 0;
	else{
		ld a=x[i]-x[j],b=y[i]-y[j],c=z[i]-z[j];
		return sqrt(a*a+b*b+c*c);
	}
}
void bfs(){
	queue<int>q;
	q.push(s);ge[s]=1;
	while(SZ(q)){
		int u=q.front();q.pop();
		U(i,u){
			if(ge[v[i]]==1)continue;
			else{
				ge[v[i]]=1;q.push(v[i]);
				if(v[i]==t)return;
			}
		}
	}
}
int main(){
	int T;read(T);while(T--){
		memset(head,0,sizeof(head));
		memset(ge,0x3f,sizeof(ge));
		read(n);scanf("%Lf %Lf",&h,&r);rep(i,1,n)scanf("%Lf %Lf %Lf",&x[i],&y[i],&z[i]);
		s=n+1;t=n+2;
		rep(i,1,n)rep(j,1,n)if(i^j)if(calc(i,j)-2*r<=ex)add(i,j);
		rep(i,1,n)if(h-z[i]-r<=ex)add(s,i);rep(i,1,n)if(z[i]-0-r<=ex)add(i,t);
		bfs();
		if(ge[t]<0x3f3f3f3f)printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/hangzz/p/13405555.html