/* 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 ;
}
分享到:
相关推荐
基于Pyqt5+Dijkstra算法实现的校园地图导览python源码 基于Pyqt5+Dijkstra算法实现的校园地图导览python源码 基于Pyqt5+Dijkstra算法实现的校园地图导览python源码 基于Pyqt5+Dijkstra算法实现的校园地图导览python...
毕设项目:基于springboot+mysql+Dijkstra算法实现物流优化管理系统.zip主要针对计算机相关专业的正在做课程设计和期末大作业的学生和需要项目实战练习的学习者。包含全部项目源码、该项目可以直接使用、项目都经过...
代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法...
最短路径Dijkstra算法-最短路Dijkstra算法.rar 最短路径Dijkstra算法
1、基于springboot+mysql+Dijkstra算法实现物流优化管理系统源码+项目说明(课程设计).zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大...
毕设项目:基于springboot+mysql+Dijkstra算法实现物流优化管理系统 本资源中的源码都是...资源项目的难度比较适中,内容都是经过专业老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。
dijkstra算法,最短路问题Dijkstra算法,网络无负权的最短问题Dijkstra算法
最短路Dijkstra算法 Matlab代码Function部分,通用各种类型网络
Dijkstra算法求最短路,利用C++程序设计,希望能对你有所帮助
标准C的图的实现+BFS和DFS遍历+Dijkstra算法+Prim算法+Kruskal算法实现,纯手写!下载后如有疑问可以私信联系!全部手撸,一键运行,都封装成函数了,易读性很强
基于Pyqt5+Dijkstra算法实现的校园地图导览python源码+项目使用说明.zip 语言:Python 主要依赖包: PyQt5 主要算法: Dijkstra 通过工程文件 - > 在配置好的IDE中运行 main.py - > 或cd 进入工程目录 python -...
文档最短路问题Dijkstra算法提取方式是百度网盘分享地址
【老生谈算法】floyd最短路算法Dijkstra最短路算法Matlab程序.doc
Dijkstra算法最简单的实现方法是用一个链表或者数组来存储所有顶点的集合Q,所以搜索Q中最小元素的运算(Extract-Min(Q))只需要线性搜索Q中的所有元素。这样的话算法的运行时间是O(n2)。
图论Dijkstra最短路算法matlab通用程序,有实例。希望对大家有用
蚁群算法+Dijkstra算法=二维路径规划,基于蚁群算法的机器人路径规划,matlab源码
蚁群算法+Dijkstra算法=二维路径规划,基于蚁群算法的机器人路径规划,matlab源码.rar