一、传送门
http://poj.org/problem?id=1556
二、算法分析说明与代码编写指导
建图的方法是:
如果两个点所在墙的编号相差 1 (起点和终点的编号记为 0 和 4n +1),那么把这两点连起来(无向边);
如果两个点在同一个墙上,这两点不连边;
如果两个点中间隔了其它的墙,需要先判断是否能直接到达而不是被中间的墙挡住。判断的方法是:把这两点连一条直线(得到斜截式 y = kx + b),考察中间的墙的开口部分是否经过直线。若是,则这堵墙不会挡住这两点的直连边;否则,会挡住,这两点不可以连边。
建完图以后直接跑一次最短路就可以了。
Dijkstra 算法
wid 返回一个点所在墙的编号。1、2、3、4 所在的墙编号为 1;5、6、7、8 对应编号 2,以此类推。
三、AC 代码
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<vector>
#pragma warning(disable:4996)
using namespace std;
struct wall {
double x, y[4]; }; struct edge {
int v; double w; }; struct point {
int id; double x, y; };
const double dm = 1e9; const int nm = 74, wm = 20;
int m, n, t, x, y; wall w[wm]; vector<edge> g[nm]; point p[nm]; edge e; bitset<nm> v; double d[nm + 1];
inline double dist(const point& p, const point& q) {
return sqrt(pow(p.x - q.x, 2) + pow(p.y