P3958 奶酪

  就是一道并查集问题,写起来也不算麻烦,而且数据范围比较优秀,可以满足O(n^2)的做法。

  思路也很容易形成:

    先合并所有洞,再找最下面有没有洞。找的过程中,再判断能不能到达最顶层就好了。(反正也没问最短路线不是嘛~ :^) )

  代码:

#include<cstdio>
#include<cmath>
using namespace std;
#define int long long
int T,n,h,r;
int a,b,c;
bool flag;
int par[1010];
struct xyz
{
    int x,y,z;
} s[1010];
double dis(int x,int y,int z,int nx,int ny,int nz)
{
    return sqrt((x-nx)*(x-nx)+(y-ny)*(y-ny)+(z-nz)*(z-nz));
}
int find(int xx)
{
    if(xx==par[xx])
        return xx;
    else
        return par[xx]=find(par[xx]);
}
void merge(int xx,int yy)
{
    par[find(xx)]=find(yy);
}
main()
{
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&n,&h,&r);
            for(int i=1;i<=n;i++)
            {
                scanf("%lld%lld%lld",&a,&b,&c);
                s[i].x=a;
                s[i].y=b;
                s[i].z=c;
                par[i]=i;
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j)
                        continue;
                    if(dis(s[i].x,s[i].y,s[i].z,
                    s[j].x,s[j].y,s[j].z)<=2*r)
                        merge(i,j);
                }
            }
        for(int i=1;i<=n;i++)
        {
            if(s[i].z-r<=0)
            {
                for(int j=1;j<=n;j++)
                {
                    if(s[j].z+r>=h)
                    {
                        if(find(i)==find(j))
                        {
                            printf("Yes
");
                            flag=1;
                            break;
                        }
                    }
                }
                if(flag==1)
                    break;
            }
        }
        if(flag==0)
            printf("No
");
        flag=0;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/popo-black-cat/p/10050187.html