UVA 1001:Say Cheese(最短路)

 
问题描述:

Once upon a time, in a giant piece of cheese, there lived a cheese mite named Amelia Cheese Mite.Amelia should have been truly happy because she was surrounded by more delicious cheese than shecould ever eat. Nevertheless, she felt that something was missing from her life.One morning, her dreams about cheese were interrupted by a noise she had never heard before. Butshe immediately realized what it was - the sound of a male cheese mite, gnawing in the same piece ofcheese! (Determining the gender of a cheese mite just by the sound of its gnawing is by no means easy,but all cheese mites can do it. That’s because their parents could.)Nothing could stop Amelia now. She had to meet that other mite as soon as possible. Thereforeshe had to find the fastest way to get to the other mite. Amelia can gnaw through one millimeter ofcheese in ten seconds. But it turns out that the direct way to the other mite might not be the fastestone. The cheese that Amelia lives in is full of holes. These holes, which are bubbles of air trappedin the cheese, are spherical for the most part. But occasionally these spherical holes overlap, creatingcompound holes of all kinds of shapes. Passing through a hole in the cheese takes Amelia essentiallyzero time, since she can fly from one end to the other instantly. So it might be useful to travel throughholes to get to the other mite quickly.For this problem, you have to write a program that, given the locations of both mites and the holesin the cheese, determines the minimal time it takes Amelia to reach the other mite. For the purposes ofthis problem, you can assume that the cheese is infinitely large. This is because the cheese is so largethat it never pays for Amelia to leave the cheese to reach the other mite (especially since cheese-miteeaters might eat her). You can also assume that the other mite is eagerly anticipating Amelia’s arrivaland will not move while Amelia is underway.

 

Input

The input file contains descriptions of several cheese mite test cases. Each test case starts with a linecontaining a single integer n (0 ≤ n ≤ 100), the number of holes in the cheese. This is followed byn lines containing four integers xi, yi, zi, ri each. These describe the centers (xi, yi, zi) and radii ri(ri > 0) of the holes. All values here (and in the following) are given in millimeters.The description concludes with two lines containing three integers each. The first line contains thevalues xA, yA, zA, giving Amelia’s position in the cheese, the second line containing xO, yO, zO, givesthe position of the other mite.The input file is terminated by a line containing the number ‘-1’.

 

Output

For each test case, print one line of output, following the format of the sample output. First print thenumber of the test case (starting with 1). Then print the minimum time in seconds it takes Ameliato reach the other mite, rounded to the closest integer. The input will be such that the rounding isunambiguous.

 

Sample Input

1
20 20 20 1
0 0 0
0 0 10
1
5 0 0 4
0 0 0
10 0 0
-1

 

Sample Output

Cheese 1: Travel time = 100 sec
Cheese 2: Travel time = 20 sec

 

题意:(这里是题目的改造版)

首先是在三维空间中,给出一些球的球心坐标以及半径,然后给出两只老鼠的初始位置,问其中一只老鼠想要寻找另一只的最短路径。

路径中每个单位长度会花费10s时间,如果在球中的话是不花费时间的。


我们可以把两只老鼠的位置想象成球,半径为0。

然后两点之间的最短距离便是两个球心之间的距离-两球半径和。如果两球半径和大于球心距的话就表明这两点之间距离为0。

根据这一特点建图,然后就是最短路模版啦!Floyd比较好写一点。

 

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<math.h>
#define INF (1<<30)
using namespace std;

struct edge
{
    double x,y,z,r;
} point[105];

double mapp[105][105];
double getlin(edge a,edge b)        //求两个球之间的距离
{
    double line=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));
    if(a.r+b.r>=line)return 0;
    else return line-a.r-b.r;
}
int main()
{
    int n;
    for(int T=1; ~scanf("%d",&n)&&n!=-1; T++)
    {
        for(int i=2; i<n+2; i++)
            scanf("%lf%lf%lf%lf",&point[i].x,&point[i].y,&point[i].z,&point[i].r);
        for(int i=0; i<2; i++)
            scanf("%lf%lf%lf",&point[i].x,&point[i].y,&point[i].z),point[i].r=0;
        for(int i=0; i<n+2; i++,mapp[i][i]=0)
            for(int j=0; j<i; j++)
                mapp[i][j]=mapp[j][i]=getlin(point[i],point[j]);    //建图
        for(int k=0; k<n+2; k++)                                    //Floyd
            for(int i=0; i<n+2; i++)
                for(int j=0; j<n+2; j++)
                    mapp[i][j]=min(mapp[i][j],mapp[i][k]+mapp[k][j]);
        printf("Cheese %d: Travel time = %.0lf sec\n",T,mapp[0][1]*10);
    }
    return 0;
}