K: 奶酪
时间限制: 1 Sec 内存限制: 128 MB提交: 115 解决: 30
[ 提交][ 状态][ 讨论版]
题目描述
现有一块大奶酪,它的高度为 h ,它的长度和宽度我们可以认为是无限大的,奶酪中间有许多半径相同的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中,奶酪的下表面为 z = 0 ,奶酪的上表面为 z = h 。
现在,奶酪的下表面有一只小老鼠 Jerry ,它知道奶酪中所有空洞的球心所在的坐标。如果两个空洞相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个空洞,特别地,如果一个空洞与下表面相切或是相交, Jerry 则可以从奶酪下表面跑进空洞;如果一个空洞与上表面相切或是相交, Jerry 则可以从空洞跑到奶酪上表面。
位于奶酪下表面的 Jerry 想知道,在不破坏奶酪的情况下,能否利用已有的空洞跑到奶酪的上表面去 ?
P1(x1,y1,z1)、P2(x_2,y_2,z_2)P2(x2,y2,z2)的距离公式如下:
现在,奶酪的下表面有一只小老鼠 Jerry ,它知道奶酪中所有空洞的球心所在的坐标。如果两个空洞相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个空洞,特别地,如果一个空洞与下表面相切或是相交, Jerry 则可以从奶酪下表面跑进空洞;如果一个空洞与上表面相切或是相交, Jerry 则可以从空洞跑到奶酪上表面。
位于奶酪下表面的 Jerry 想知道,在不破坏奶酪的情况下,能否利用已有的空洞跑到奶酪的上表面去 ?
P1(x1,y1,z1)、P2(x_2,y_2,z_2)P2(x2,y2,z2)的距离公式如下:
![](http://exam.upc.edu.cn/upload/image/20171121/20171121173140_10044.jpg)
输入
包含多组数据。
第一行,包含一个正整数 T,代表该输入文件中所含的数据组数。
接下来是 T 组数据,每组数据的格式如下:
第一行包含三个正整数 n,h 和 r,两个数之间以一个空格分开,分别代表奶酪中空洞的数量,奶酪的高度和空洞的半径。
接下来的 n 行,每行包含三个整数 x、y、z,两个数之间以一个空格分开,表示空洞球心坐标为(
第一行,包含一个正整数 T,代表该输入文件中所含的数据组数。
接下来是 T 组数据,每组数据的格式如下:
第一行包含三个正整数 n,h 和 r,两个数之间以一个空格分开,分别代表奶酪中空洞的数量,奶酪的高度和空洞的半径。
接下来的 n 行,每行包含三个整数 x、y、z,两个数之间以一个空格分开,表示空洞球心坐标为(
输出
输出包含T行,分别对应T组数据的答案,如果在第i组数据中,Jerry能从下表面跑到上表面,则输出Yes,如果不能,则输出No(均不包含引号)。
样例输入
3
2 4 1
0 0 1
0 0 3
2 5 1
0 0 1
0 0 4
2 5 2
0 0 2
2 0 4
样例输出
Yes
No
Yes
提示
【题意】
题意很明确 能否从下面到上面
【思路】
转换方向, 就是一个图, 类似于 网络流 有一个 源点 和汇点, 唯一不同的就是 图里面 没有权值, 这样 其实 也可以用并查集, 源点 汇点 看看 最后是否在一个队里, 如果在 那么 就yes 否则 就 no spfa 好理解, 从源点看看 汇点 可不可达
【代码实现】
SPFA 头文件 什么的 可以忽略~
//#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define S1(n) scanf("%d",&n)
#define SL1(n) scanf("%I64d",&n)
#define S2(n,m) scanf("%d%d",&n,&m)
#define SL2(n,m) scanf("%I64d%I64d",&n,&m)
#define Pr(n) printf("%d\n",n)
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FI(n) IO::read(n)
#define Be IO::begin()
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e5+5;
const int MAXN=50005;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};
namespace IO {
const int MT = 5e7;
char buf[MT]; int c,sz;
void begin(){
c = 0;
sz = fread(buf, 1, MT, stdin);//一次性输入
}
template<class T>
inline bool read(T &t){
while( c < sz && buf[c] != '-' && ( buf[c]<'0' || buf[c] >'9')) c++;
if( c>=sz) return false;
bool flag = 0; if( buf[c]== '-') flag = 1,c++;
for( t=0; c<=sz && '0' <=buf[c] && buf[c] <= '9'; c++ ) t= t*10 + buf[c]-'0';
if(flag) t=-t;
return true;
}
}
ll inv[maxn*2];
inline void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){ x=1; y=0; d=a; }else{ ex_gcd(b,a%b,d,y,x); y-=x*(a/b);};}
inline ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
inline ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
inline ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;}
inline ll inv_exgcd(ll a,ll n){ll d,x,y;ex_gcd(a,n,d,x,y);return d==1?(x+n)%n:-1;}
inline ll inv1(ll b){return b==1?1:(MOD-MOD/b)*inv1(MOD%b)%MOD;}
inline ll inv2(ll b){return qpow(b,MOD-2);}
struct node{
ll x,y,z;
}a[MAXN];
struct EDGE{
ll v,next;
ll w;
}edge[MAXN];
ll head[MAXN],cot;
int st=0,ed=MAXN-5;
int vis[MAXN];
void init()
{
cot=0;
mem(head,-1);
}
void add(ll u,ll v)
{
edge[++cot].v=v;
edge[cot].next=head[u];
head[u]=cot;
edge[++cot].v=u;
edge[cot].next=head[v];
head[v]=cot;
}
ll dis(ll x,ll y)
{
return (pow(a[x].x-a[y].x,2)+pow(a[x].y-a[y].y,2)+pow(a[x].z-a[y].z,2));
}
bool SPFA()
{
mem(vis,0);
queue<ll>Q;
Q.push(st);
vis[st]=1;
while(!Q.empty())
{
ll u=Q.front();
Q.pop();
// vis[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
if(!vis[edge[i].v])
{
// printf("nest is %d\n",edge[i].v);
vis[edge[i].v]=1;
Q.push(edge[i].v);
}
}
}
}
int main()
{
int T;
ll n,h,r;
cin>>T;
while(T--)
{
init();
memset(a,0,sizeof(a));
mem(edge,0);
scanf("%lld %lld %lld",&n,&h,&r);
for(ll i=1;i<=n;i++)
{
scanf("%lld %lld %lld",&a[i].x,&a[i].y,&a[i].z);
}
for(ll i=1;i<=n;i++)
{
if(r>=a[i].z)
add(st,i);
if(a[i].z+r>=h)
add(i,ed);
for(ll j=i+1;j<=n;j++)
{
if(dis(i,j)<= (4*r*r))
{
//printf("+++ %lld %lld \n",dis(i,j),2*r);
add(i,j);
}
}
}
SPFA();
if(vis[ed])
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
并查集
//#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define S1(n) scanf("%d",&n)
#define SL1(n) scanf("%I64d",&n)
#define S2(n,m) scanf("%d%d",&n,&m)
#define SL2(n,m) scanf("%I64d%I64d",&n,&m)
#define Pr(n) printf("%d\n",n)
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FI(n) IO::read(n)
#define Be IO::begin()
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e5+5;
const int MAXN=50005;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};
namespace IO {
const int MT = 5e7;
char buf[MT]; int c,sz;
void begin(){
c = 0;
sz = fread(buf, 1, MT, stdin);//一次性输入
}
template<class T>
inline bool read(T &t){
while( c < sz && buf[c] != '-' && ( buf[c]<'0' || buf[c] >'9')) c++;
if( c>=sz) return false;
bool flag = 0; if( buf[c]== '-') flag = 1,c++;
for( t=0; c<=sz && '0' <=buf[c] && buf[c] <= '9'; c++ ) t= t*10 + buf[c]-'0';
if(flag) t=-t;
return true;
}
}
ll inv[maxn*2];
inline void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){ x=1; y=0; d=a; }else{ ex_gcd(b,a%b,d,y,x); y-=x*(a/b);};}
inline ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
inline ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
inline ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;}
inline ll inv_exgcd(ll a,ll n){ll d,x,y;ex_gcd(a,n,d,x,y);return d==1?(x+n)%n:-1;}
inline ll inv1(ll b){return b==1?1:(MOD-MOD/b)*inv1(MOD%b)%MOD;}
inline ll inv2(ll b){return qpow(b,MOD-2);}
int st=0,ed=MAXN-5;
ll h,n,r;
struct node{
ll x,y,z;
}a[MAXN];
ll pre[MAXN];
ll finds(ll x)
{
return pre[x]==x? x:(pre[x]=finds(pre[x]));
}
void join(ll x,ll y)
{
ll fx=finds(x);ll fy=finds(y);
//printf("%d is %d | %d is %d\n",x,fx,y,fy);
if(fx!=fy)
pre[fx]=fy;
}
void init()
{
pre[st]=st;
pre[ed]=ed;
for(ll i=1;i<=n;i++)
{
pre[i]=i;
}
}
ll dis(int x,int y)
{
return pow(a[x].x-a[y].x,2)+pow(a[x].y-a[y].y,2)+pow(a[x].z-a[y].z,2);
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%lld %lld %lld",&n,&h,&r);
init();
for(int i=1;i<=n;i++)
{
scanf("%lld %lld %lld",&a[i].x,&a[i].y,&a[i].z);
if(r>=a[i].z)
{
join(i,st);
}
if(r+a[i].z>=h)
{
join(i,ed);
}
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(dis(i,j)<=(4*r*r))
{
join(i,j);
}
}
}
int cot=0;
//printf("pres is %d \n",finds(ed));
if(finds(st)==finds(ed) )//|| finds(ed)==st)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
123