UVa 1001 Say Cheese (Dijkstra)

题意:给定一个三维空间的一些球和起始位置和结束位置,问你最短要花的时间是多少。

析:建图,所有的位置都建立图,边权就是距离,最小求一次最短路即可。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<double, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-5;
const int maxn = 100 + 10;
const int mod = 1e6;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
  return r >= 0 && r < n && c >= 0 && c < m;
}
struct Point{
  double x, y, z, r;
};
Point a[maxn];
double G[maxn][maxn];
double d[maxn];
double distant(int i, int j){
  return max(0.0, sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x) + (a[i].y-a[j].y)*(a[i].y-a[j].y) + (a[i].z-a[j].z)*(a[i].z-a[j].z)) - a[i].r - a[j].r);
}

double dijkstra(int s, int t){
  priority_queue<P, vector<P>, greater<P> >pq;
  fill(d, d+n+5, INF);
  d[s] = 0.0;
  pq.push(P(0.0, s));

  while(!pq.empty()){
    P p = pq.top();  pq.pop();
    if(p.second == t)  return p.first;
    int u = p.second;
    if(d[u] < p.first)  continue;
    for(int i = 0; i < n+2; ++i){
      if(d[i] > d[u] + G[u][i]){
        d[i] = d[u] + G[u][i];
        pq.push(P(d[i], i));
      }
    }
  }
}

int main(){
  int kase = 0;
  while(scanf("%d", &n) == 1 && n >= 0){
    for(int i = 0; i < n; ++i)
      scanf("%lf %lf %lf %lf", &a[i].x, &a[i].y, &a[i].z, &a[i].r);
    int s = n, t = n+1;
    for(int i = n; i < n+2; ++i)  scanf("%lf %lf %lf", &a[i].x, &a[i].y, &a[i].z);
    a[n].r = a[n+1].r = 0.0;
    for(int i = 0; i < n+2; ++i)
      for(int j = i+1; j < n+2; ++j)
        G[i][j] = G[j][i] = distant(i, j);
    double ans = dijkstra(s, t) * 10;
    printf("Cheese %d: Travel time = %.f sec\n", ++kase, ans);
  }
  return 0;
}
时间: 2024-08-01 22:44:08

UVa 1001 Say Cheese (Dijkstra)的相关文章

UVA 1001 Say Cheese

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

UVA 1001 Say Cheese (最短路,floyd)

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

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 10801]Lift Hopping[Dijkstra][建图]

题目链接:[UVA 10801]Lift Hopping[Dijkstra][建图] 题意分析: 从0层开始,一共有n台电梯供你到达目的地k层.每台电梯往上走一层都要消耗t[i]的时间,并且电梯只能在特定的楼层停下,换乘电梯要花费60s的时间,而且呢,你不能用楼梯上楼,只能搭电梯....(hentai!)问:最快到达楼层k的时间是多少?不能到达就输出-1. 解题思路: 这题技巧就是体现在建图上,图建好了,用dijkstra跑一遍就行了. 具体建图就是用mp[i][j]代表从楼层i到楼层j的最小距

UVA - 11374 Airport Express (Dijkstra模板+枚举)

Description Problem D: Airport Express In a small city called Iokh, a train service, Airport-Express, takes residents to the airport more quickly than other transports. There are two types of trains in Airport-Express, the Economy-Xpress and the Comm

1001 - Say Cheese (Dijkstra算法)

该题是求两点间的最短路问题,用Dijkstra算法比较快 ,跑了0.003s . 方法很简单,将圆看成结点,直接判断两个圆是否相交,如果相交距离为0,否则距离为圆心间距离减去两圆半径. 起点和终点也可以看成是一个半径为0的圆 . 这样就变成了两点间的最短路问题,适合用Dijkstra算法求解.  比较坑的是该题说了数据范围n最大100,但是我开了105竟然RE ,看成505就过了 .  所以在占用内存不多的情况下还是开大一点好 . 细节参见代码: #include<bits/stdc++.h>

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

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

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

uva 1001 建图+最短路

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