/* THE PROGRAM IS MADE BY PYY */
/*----------------------------------------------------------------------------//
Copyright (c) 2011 panyanyany All rights reserved.
URL : http://acm.hdu.edu.cn/showproblem.php?pid=1245
Name : 1245 Saving James Bond
Date : Tuesday, January 17, 2012
Time Stage : 8 hours
Result:
5268663 2012-01-17 16:34:56 Accepted 1245
203MS 320K 4753 B
C++ pyy
Test Data :
Review :
耗时8小时左右,十次提交,终于AC,也算是我做的少有的大题目了,唔,
以后要多做一些大题目啊。
据说此题卡精度……
//----------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std ;
#define MEM(a, v) memset (a, v, sizeof (a))
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
#define SQR(x) ((x)*(x))
#define EPS 1e-8
#define GT(x, y) (((x) - (y)) > EPS) // 大于
#define EQ(x, y) (fabs((x) - (y)) <= EPS) // 等于
#define LT(x, y) GT(y, x) // 小于
#define GET(x, y) (!LT(x, y)) // >=
#define LET(x, y) (!GT(x, y)) // <=
#define INF 0x3f3f3f3f
#define MAXN 103
#define DELTA 50
#define RADIUS 7.5
inline double getdist (int i, int j) ;
typedef struct tagPOINT {
int x, y ;
} POINT ;
struct EDGE {
int des ;
double dis ;
EDGE () {}
EDGE (int e, double ds) :
des(e), dis(ds) {}
};
bool used[MAXN] ;
int n, cnt ;
int step[MAXN] ;
double d ;
double dist[MAXN] ;
vector<EDGE> graph[MAXN] ; // store edges
POINT map[MAXN] ;
void init ()
{
int i ;
for (i = 0 ; i < MAXN ; ++i)
graph[i].clear () ;
memset (map, 0, sizeof (map)) ;
}
inline double getdist (double x1, double y1, double x2, double y2)
{
return sqrt (SQR(x1-x2) + SQR(y1-y2)) ;
}
inline double getdist (int i, int j)
{
return getdist (map[i].x, map[i].y, map[j].x, map[j].y) ;
}
inline double tostart (int i)
{
// RADIUS : 别忘了小岛是有半径的,一开始把 diameter 看成是半径了,晕死啊
return getdist (map[i].x, map[i].y, DELTA, DELTA) - RADIUS;
}
inline double toend (int i)
{
return min (
min (map[i].x, map[i].y),
min (abs (100-map[i].x), abs(100-map[i].y))) ;
}
void makegraph ()
{
int i, j ;
double s, e ;
for (i = 1 ; i <= n ; ++i)
{
// 到小岛的距离
s = tostart (i) ;
// 到岸边的距离
e = toend (i) ;
// 从小岛可以直接跳上的点
if (GT(s, 0) && GET(d, s))
graph[0].push_back(EDGE(i, s)) ;
// 可以直接跳到岸上的点
if (GT(e, 0) && GET(d, e))
graph[i].push_back(EDGE(n+1, e)) ;
}
// 各点到各点的可行的边
for (i = 1 ; i <= n ; ++i)
for (j = 1 ; j <= n ; ++j)
{
if (i == j)
continue ;
s = getdist (i, j) ;
if (GET(d, s))
{
graph[i].push_back(EDGE(j, s)) ;
}
}
}
// dijkstra 中处理的各点都应具有平等的身份,这样才能方便处理,
// 像 “小岛” 和 “岸边”这种特殊情况要想办法预先转化为与“点”
// 一样的角色
void dijkstra (const int start, const int end)
{
int i, j, id ;
int iMinPath ;
double MinPath, s ;
MEM (step, 0) ;
MEM (used, 0) ;
for (i = start ; i <= end ; ++i)
dist[i] = INF * 1.0 ;
// 从小岛可以直接跳上的点
for (i = 0 ; i < graph[start].size() ; ++i)
{
id = (graph[start][i]).des ;
dist[id] = graph[start][i].dis ;
step[id] = 1 ;
}
for (j = start ; j <= end ; ++j)
{
iMinPath = 0 ;
MinPath = INF * 1.0 ;
for (i = start ; i <= end ; ++i)
if (!used[i] && dist[i] < MinPath)
{
iMinPath = i ;
MinPath = dist[i] ;
}
used[iMinPath] = 1 ;
for (i = 0 ; i < graph[iMinPath].size() ; ++i)
{
// 能从 iMinPath 到达的点 id
id = graph[iMinPath][i].des ;
// 原路径加上 边(iMinPath, id) 的距离
s = dist[iMinPath] + graph[iMinPath][i].dis ;
if (!used[id] && LT(s, dist[id]))
{
dist[id] = s ;
step[id] = step[iMinPath] + 1 ;
}
}
}
}
int main ()
{
int i ;
int x, y ;
while (~scanf ("%d%lf", &n, &d))
{
init () ;
for (i = 1 ; i <= n ; ++i)
{
scanf ("%d%d", &x, &y) ;
// DELTA 的意思,是把整幅图向右向上各平移了 DELTA 个单位
map[i].x = x + DELTA ;
map[i].y = y + DELTA ;
}
// 可以一步直接跳出来的,直接输出
// 本来是想直接输出 d 而不是 50-RADIUS 的,
// 但考虑到 James Bond 应该不至于每一步都固定吧
if (GET(d, 50-RADIUS))
printf ("%.2lf %d\n", 50-RADIUS, 1) ;
else
{
// 建图,处理小岛和岸边这两大麻烦。
// 参考大牛的做法,把这两处处理成两点:0 和 n+1
// 其实我感觉本题的难处可能就是处理这两点的问题上
// 因为一开始想不到什么好办法,于是在 dijkstra 中处理
// 结果弄得很麻烦,因为问题分散了,一开始没有建好图,
// 后面就要步步惊心地小心注意区分好 "小岛、岸边与各点"
// 总之一句话:把问题在源头处理好,就不会污染整个流程了!
makegraph () ;
dijkstra(0, n+1) ;
if (LT(dist[n+1], INF * 1.0))
printf ("%.2lf %d\n", dist[n+1], step[n+1]) ;
else
puts ("can't be saved") ;
}
}
return 0 ;
}
分享到:
相关推荐
《杭电HDU ACM培训课件》是一份珍贵的学习资源,源自杭州电子科技大学的ACM竞赛培训课程。这些课件是官方论坛上分享的,旨在为那些积分不足无法获取资源或者对ACM编程竞赛感兴趣的初学者提供帮助。下面将详细阐述这...
基于Pyqt5+Dijkstra算法实现的校园地图导览python源码 基于Pyqt5+Dijkstra算法实现的校园地图导览python源码 基于Pyqt5+Dijkstra算法实现的校园地图导览python源码 基于Pyqt5+Dijkstra算法实现的校园地图导览python...
毕设项目:基于springboot+mysql+Dijkstra算法实现物流优化管理系统.zip主要针对计算机相关专业的正在做课程设计和期末大作业的学生和需要项目实战练习的学习者。包含全部项目源码、该项目可以直接使用、项目都经过...
基于java+dijkstra算法实现上海地铁换乘线路的查询+源码+实现原理解析,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于java+dijkstra算法实现上海地铁换乘...
代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法...
毕设项目:基于springboot+mysql+Dijkstra算法实现物流优化管理系统 本资源中的源码都是...资源项目的难度比较适中,内容都是经过专业老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。
【作品名称】:基于Matlab+Dijkstra和时间窗规划的AGV调度算法 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:基于...
1、基于springboot+mysql+Dijkstra算法实现物流优化管理系统源码+项目说明(课程设计).zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大...
最短路径Dijkstra算法是图论中的一个经典算法,由荷兰计算机科学家艾兹格·迪科斯彻在1956年提出,主要用于解决单源最短路径问题。该算法适用于加权有向或无向图,寻找从起始节点到其他所有节点的最短路径。在实际...
标题中的“最短路径+dijkstra+matlab代码+算法效率测试”揭示了本文将要讨论的是图论中的一个经典算法——Dijkstra算法,并且在MATLAB环境下实现与测试该算法的效率。MATLAB是一款强大的数学计算软件,常用于科学...
Saving James Bond - Easy Version (25)"暗示这是一个关于图论问题的案例,可能是从编程挑战或者算法教学的角度出发,其中"Saving James Bond"可能是一个模拟场景,让学习者通过解决图形结构的问题来拯救詹姆斯·...
dijkstra算法,最短路问题Dijkstra算法,网络无负权的最短问题Dijkstra算法
最短路Dijkstra算法 Matlab代码Function部分,通用各种类型网络
AGV调度_基于Matlab+Dijkstra算法+时间窗规划实现的AGV调度算法_附项目源码_优质项目实战
基于Pyqt5+Dijkstra算法实现的校园地图导览python源码+项目使用说明.zip 语言:Python 主要依赖包: PyQt5 主要算法: Dijkstra 通过工程文件 - > 在配置好的IDE中运行 main.py - > 或cd 进入工程目录 python -...
【老生谈算法】floyd最短路算法Dijkstra最短路算法Matlab程序.doc
Dijkstra算法最简单的实现方法是用一个链表或者数组来存储所有顶点的集合Q,所以搜索Q中最小元素的运算(Extract-Min(Q))只需要线性搜索Q中的所有元素。这样的话算法的运行时间是O(n2)。