luogu 3958 奶酪

noip2017 D2T1 奶酪 某zz选手没有想到可以用并查集来做,直接用了dijskstra,结果被ccf老爷机卡成了70分

题目大意:

现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪中间有许多半径相同的球形空洞

我们可以在这块奶酪中建立空间坐标系,在坐标系中, 奶酪的下表面为z=0,奶酪的上表面为 z=h。

现在,知道奶酪中所有空洞的球心所在的坐标,起点为奶酪的下表面 如果两个空洞相切或是相交,则可以从其中一个空洞跑到另一个空洞

特别地,如果一个空洞与下表面相切或是相交,则可以从奶酪下表面跑进空洞;如果一个空洞与上表面相切或是相交,则可以从空洞跑到奶酪上表面。

位于奶酪下表面的 Jerry 想知道,在 不破坏奶酪 的情况下,能否利用已有的空洞跑 到奶酪的上表面去?

空间内两点P1(x1,y1,z1)、P2(x2,y2,z2)的距离公式如下:

dist(P1,P2)=sqrt((x1x2)2+(y1y2)2+(z1z2)^2​)

思路:

随便用并查集或dij或spfa来做,判断上下表面是否连通即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<queue>
 8 #include<map>
 9 #include<vector>
10 #define inf 2147483611
11 #define ll long long
12 #define MAXN 1010
13 #define P pair<int,int>
14 #define mp(a,b) make_pair(a,b)
15 using namespace std;
16 inline int read()
17 {
18     int x=0,f=1;char ch=getchar();
19     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
20     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
21     return x*f;
22 }
23 struct node {double x,y,z;}a[MAXN];
24 double dist(node a,node b)
25 {
26     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
27 }
28 int T,n,h,r,nxt[MAXN*MAXN],fst[MAXN],to[MAXN*MAXN],cnt,dis[MAXN];
29 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
30 void dij()
31 {
32     priority_queue<P,vector<P>,greater<P> > q;
33     q.push(mp(0,n+1));memset(dis,127,sizeof(dis));dis[n+1]=0;
34     while(!q.empty())
35     {
36         int k=q.top().second;q.pop();
37         for(int i=fst[k];i;i=nxt[i])
38         {
39             if(dis[to[i]]>dis[k]+1) {dis[to[i]]=dis[k]+1;q.push(mp(dis[to[i]],to[i]));}
40         }
41         if(dis[n+2]!=2139062143) break;
42     }
43     if(dis[n+2]!=2139062143) puts("Yes");
44     else puts("No");
45 }
46 int main()
47 {
48     //freopen("cheese.in","r",stdin);
49     //freopen("cheese.out","w",stdout);
50     T=read();
51     while(T--)
52     {
53         memset(nxt,0,sizeof(nxt));
54         memset(fst,0,sizeof(fst));
55         n=read(),h=read(),r=read();
56         for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z);
57         for(int i=1;i<=n;i++)
58         {
59             if(a[i].z<=r) add(n+1,i);
60             if(a[i].z+r>=h) add(i,n+2);
61             for(int j=1;j<=n;j++)
62             {
63                 if(i==j) continue;
64                 if(dist(a[i],a[j])<=2*r) {add(i,j);add(j,i);}
65             }
66         }
67         dij();
68     }
69 }
View Code

 

posted @ 2017-11-21 20:12  jack_yyc  阅读(261)  评论(0编辑  收藏  举报