uva 1001(最短路)

题意:在一个三维的奶酪里面有n(n<=100)个洞,老鼠A想到达老鼠B的位置,在洞里面可以瞬间移动,在洞外面的移动速度为10秒一个单位,求最短时间

题解:如果两个洞相交,那么d[i][j]=0;如果不相交,那么d[i][j]=dist-(r[i]+r[j]),dist为这两个洞圆心之间的欧几里得距离

再用Dijkstra处理就可以了

#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define ll long long
#define _cle(m, a) memset(m, a, sizeof(m))
#define repu(i, a, b) for(int i = a; i < b; i++)
#define repd(i, a, b) for(int i = b; i >= a; i--)
#define sfi(n) scanf("%d", &n)
#define sfd(n) scanf("%lf", &n)
#define pfi(n) printf("%d\n", n)
#define pfd(n) printf("%lf\n", n)
#define sfi2(n, m) scanf("%d%d", &n, &m)
#define sfd2(n, m) scanf("%lf%lf", &n, &m)
#define pfi2(n, m) printf("%d %d\n", n, m)
#define pfi3(a, b, c) printf("%d %d %d\n", a, b, c)
#define maxn 105
double dd[maxn][maxn];
struct Cir{
   double x, y, z, r;
}c[maxn];
double get_d(Cir c1, Cir c2)
{
    return sqrt((c1.x - c2.x) * (c1.x - c2.x) +
                (c1.y - c2.y) * (c1.y - c2.y) +
                (c1.z - c2.z) * (c1.z - c2.z));
}

const double inf = 1000000000000.0;
struct Dijkstra {
    int n;    //图,须手动传入!
    double E[maxn][maxn], d[maxn];
    int p[maxn];    //最短路径,父亲

    void init(int n) {
        this->n = n;
        repu(i, 0, n) repu(j, 0, n)
        E[i][j] = dd[i][j];
    }

    void solve(int s) {
        static bool vis[maxn];

        memset(vis, 0, sizeof(vis));
        memset(p, 255, sizeof(p));
        repu(i, 0, n + 1) d[i] = inf;
        d[s] = 0.0;
        //repu(i, 0, n) pfd(d[i]);
        while(1) {
            int u = -1;
            for(int i = 0; i < n; i ++) {
                if(!vis[i] && (u == -1||d[i] < d[u])) {
                    u = i;
                }
            }
            if(u == -1 || d[u] == inf) break;
            vis[u] = true;
            for(int v = 0; v < n; v ++) {
                if(d[u] + E[u][v] < d[v]) {
                    d[v] = d[u] + E[u][v];
                    p[v] = u;
                }
            }
        }
    }
} dij;

int main()
{
    int n;
    int kase = 0;
    while(~sfi(n) && n != -1)
    {
        kase++;
        repu(i, 1, n + 1)
        sfd2(c[i].x, c[i].y), sfd2(c[i].z, c[i].r);

        sfd2(c[0].x, c[0].y), sfd(c[0].z);
        sfd2(c[n + 1].x, c[n + 1].y), sfd(c[n + 1].z);
        c[0].r = c[n + 1].r = 0.0;

        repu(i, 0, n + 2)
        repu(j, 0, n + 2)
        {
           dd[i][j] = get_d(c[i], c[j]) - (c[i].r + c[j].r);
           if(dd[i][j] < 0.0) dd[i][j] = 0.0;
           //printf("%d %d %lf\n", i, j, dd[i][j]);
        }

        dij.init(n + 2);
        dij.solve(0);

        //repu(i, 0, n + 2) pfd(dij.d[i]);
        printf("Cheese %d: Travel time = %d sec\n",
                     kase, (int)round(dij.d[n + 1] * 10.0));
    }
    return 0;
}

时间: 2025-01-03 12:37:25

uva 1001(最短路)的相关文章

uva 10269 最短路+dp

题意:有a个村庄.b个城镇, 编号分别为:1-a , a+1--a+b . 有双神奇的鞋,可以瞬时移动,可以使用k次,每次可以移动L , 但穿这双鞋的时候,不能经过城镇 , 问:从a+b 到 1 最短距离是多少? 刚开始看这个题时 , 一点思路都没有 , dp类型的题目做得太少了. 解法:进行状态压缩, 用点+使用鞋子的次数 , 来表示一个状态 , d[i][k] , 表示到 点 i 使用 k 次鞋子的最短距离是多少. 但要先进行初始化 , 求任意点之间不经过城镇的最短距离 , 用floyd算法

uva 11374 最短路+记录路径 dijkstra最短路模板

UVA - 11374 Airport Express Time Limit:1000MS   Memory Limit:Unknown   64bit IO Format:%lld & %llu [Submit]  [Go Back]  [Status] Description ProblemD: Airport Express In a small city called Iokh, a train service, Airport-Express, takes residents to t

uva 1001 建图+最短路

题意: 在一个三维的空间内求从起点到终点的最短时间花费. 其中n个洞,在洞内通过的时间花费是0,在洞外的时间花费是每单位10sec 思路: 水题 建立起点到每个洞的边,建立终点到每个洞的边,建立起点到终点的边 ,边权是到达所需的时间花费.求一次最短路即可. code: #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #i

UVA 1001 Say Cheese (最短路,floyd)

题意:一只母老鼠想要找到她的公老鼠玩具(cqww?),而玩具就丢在一个广阔的3维空间(其实可以想象成平面)上某个点,而母老鼠在另一个点,她可以直接走到达玩具的位置,但是耗时是所走过的欧几里得距离*10s.还有一种方法,就是靠钻洞,洞是球的,而在洞内怎么走都是不耗时间的.求母老鼠找到她的玩具所耗时? 思路:先要看清楚题意先!尽可能要找到洞,如果洞的半径越大,那么就可以越省时.如果老鼠和玩具都在同个洞上,那么不耗时即可找到. 其实就是求单源最短路,只是计算两点间的长度时要考虑到半径的.而且得注意两洞

UVa 1001 Say Cheese (Dijkstra)

题意:给定一个三维空间的一些球和起始位置和结束位置,问你最短要花的时间是多少. 析:建图,所有的位置都建立图,边权就是距离,最小求一次最短路即可. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <

UVa 1001 奶酪里的老鼠(Dijkstra或Floyd)

https://vjudge.net/problem/UVA-1001 题意:一个奶酪里有n个洞,老鼠在奶酪里的移动速度为10秒一个单位,但是在洞里可以瞬间移动.计算出老鼠从A点到达O点所需的最短时间. 思路:最短路问题. 我们可以把起点和终点也看成是两个洞,半径为0.这样每个洞就代表了一个点,对于两个洞而言,圆心距离大于两半径之和,此时它们之间的距离就为圆心距离-两半径之和,否则就为0. 我们在计算出任意两个洞之间的距离之后,就可以套用最短路代码来解题了.下面的代码我是用了Floyd算法. 1

Lift Hopping (Uva 10801 最短路)

题意:n个电梯,100层楼,告诉每个电梯的速度和每个电梯会停的楼层数,起点在0层,终点是第k层,另外每次换乘需要等待60秒,问从0到k的最短时间是多少. 思路:这题就是读入比较蛋疼,然后根据输入建完图后跑一下Dijkstra.在更新时加入60秒. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #i

UVA - 1001 Say Cheese(奶酪里的老鼠)(flod)

题意:无限大的奶酪里有n(0<=n<=100)个球形的洞.你的任务是帮助小老鼠A用最短的时间到达小老鼠O所在位置.奶酪里的移动速度为10秒一个单位,但是在洞里可以瞬间移动.洞和洞可以相交.输入n个球的位置和半径,以及A和O的坐标,求最短时间. 分析: 1.因为洞可以相交,所以在计算两点距离时要判断一下if(dist > num[i].r + num[j].r). 2.两球间的距离为球心间距离-两球半径,起点和终点不是球,可将半径设为0. #pragma comment(linker, &

UVA 1001 Say Cheese

题意: 一只母老鼠想要找到她的玩具,而玩具就丢在一个广阔的3维空间上某个点,而母老鼠在另一个点,她可以直接走到达玩具的位置,但是耗时是所走过的欧几里得距离*10s.还有一种方法,就是靠钻洞,洞是球形的,在洞内怎么走都是不耗时间的.求母老鼠找到她的玩具所耗时? 分析: 洞到洞的最短距离都是圆心距离减去半径.剩下的就是求单源最短路径. 代码: #include <iostream>#include <cstring>#include <cstdio>#include <