您的位置:首页 > 其它

呵呵。。。

2016-11-09 14:46 155 查看


记录一下端点间直接路径,然后跑最短路

#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

#include <set>
#include <stack>
#include <queue>
#include <vector>

#define pb push_back
#define lb lower_bound
#define sqr(x) (x)*(x)
#define lowbit(x) (x)&(-x)
#define Abs(x) ((x) > 0 ? (x) : (-(x)))
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)

#define maxn 1005
#define maxm 100005
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

template<class T> inline
void read(T& num){
num = 0; bool f = true;char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') f = false;ch = getchar();}
while(ch >= '0' && ch <= '9') {num = num * 10 + ch - '0';ch = getchar();}
num = f ? num: -num;
}
int out[100];
template<class T> inline
void write(T x,char ch){
if (x==0) {putchar('0'); putchar(ch); return;}
if (x<0) {putchar('-'); x=-x;}
int num=0;
while (x){ out[num++]=(x%10); x=x/10;}
FORM(i,num-1,0) putchar(out[i]+'0'); putchar(ch);
}
/*==================split line==================*/
const double eps=1e-8;
int n, cnt, cntl;
double dis[maxn][maxn];
int T;

struct Vec{
double x,y;
Vec(){}
Vec(double _x,double _y) :x(_x),y(_y){}
bool operator == (const Vec &k) const{
return (fabs(x - k.x) <= eps) && (fabs(y - k.y) <= eps);
}
};
typedef Vec Poi;
Poi p[maxn];
struct Line{
Poi s,t;
Line(){}
double getdis(){ return sqrt(sqr(s.x - t.x) + sqr(s.y - t.y)); }
}line[maxn];
bool eq(double x,double y){return fabs(x-y)<=eps;}
inline double cross(Poi a,Poi b){return a.x * b.y - a.y * b.x;}
inline Poi operator - (Poi a, Poi b) {return Poi(a.x - b.x, a.y - b.y); }

inline double turn(Poi a,Poi b,Poi c){return cross(b-a,c-a);}

bool judge(Poi a,Poi b){
FORP(i, 1, cntl) {
if (a == line[i].s && b == line[i].t) return true;
if (turn(a,b,line[i].s) * turn(a,b,line[i].t) < - eps &&
turn(line[i].s, line[i].t, a) * turn(line[i].s, line[i].t, b) < -eps) return false;
}
return true;
}
bool seeable(Poi a, Poi b, int x, int y){
if (x % 2 == 0) x--; if (y % 2 == 1) y++;
double k = (b.y - a.y) / (b.x - a.x);
for (int i = x; i <= y; i += 2){
double pos = (p[i].x - a.x) * k + a.y;
if (pos < p[i].y || pos > p[i + 1].y) return false;
}
return true;
}
double w;
double xx[maxn], yy[maxn];
void init(){
read(n); n++;
FORP(i, 0, maxn)
FORP(j, 0, maxn) dis[i][j] = INF;
FORP(i, 1, n) scanf("%lf%lf",&xx[i],&yy[i]);
scanf("%lf",&w);
FORP(i, 1, n){
double x = xx[i], y = yy[i];
p[++cnt] = Poi(x, y), p[++cnt] = Poi(x, y + w);
if (i > 1){
line[++cntl].s = p[cnt - 3], line[cntl].t = p[cnt - 1];
dis[cnt - 3][cnt - 1] = dis[cnt - 1][cnt - 3] = line[cntl].getdis();
line[++cntl].s = p[cnt - 2], line[cntl].t = p[cnt];
dis[cnt][cnt - 2] = dis[cnt - 2][cnt] = line[cntl].getdis();
}
}

}
struct HeapNode{
double d;
int u;
bool operator <(const HeapNode& rhs) const{
return d > rhs.d;
}
};
bool done[maxn];
double dist[maxn];
priority_queue<HeapNode> q;
void dijkstra(){
FORP(i, 0, T) dist[i] = INF;
dist[0] = 0; q.push((HeapNode){0,0});
while (!q.empty()){
HeapNode x = q.top(); q.pop();
int u = x.u;
if (done[u]) continue;
done[u] = true;
FORP(i, 0, T) if (dist[i] > dist[u] + dis[u][i]){
dist[i] = dist[u] + dis[u][i];
q.push((HeapNode){dist[i], i});
}
}
}
void work(){
T = cnt + 1;
double up = p[2].y,down = p[1].y; bool flag = true;
for (int i = 3; i <= cnt; i+= 2){
if (p[i].y > up) {flag = false; break;}
if (p[i + 1].y < down) {flag = false; break;}
if (p[i + 1].y < up) dis[0][i + 1] = dis[i + 1][0] = p[i + 1].x;
if (p[i].y > down) dis[0][i] = dis[i][0] = p[i].x;
up = min(up, p[i + 1].y); down = max(down, p[i].y);
}
if (flag) {printf("%lf\n", p[cnt].x - p[1].x); return;}
up = p[cnt].y, down = p[cnt - 1].y; flag = true;
for (int i = cnt - 2; i >= 1; i -= 2){
if (p[i - 1].y > up) {flag = false; break;}
if (p[i].y < down) {flag = false; break;}
if (p[i].y < up) dis[T][i] = dis[i][T] = p[cnt].x - p[i].x;
if (p[i - 1].y > down) dis[T][i - 1] = dis[i - 1][T] = p[cnt].x - p[i - 1].x;
up = min(up, p[i].y); down = max(down, p[i - 1].y);
}
FORP(i, 1, cnt)
FORP(j, i + 1, cnt)
if (p[i].x != p[j].x){
Line temp; temp.s = p[i]; temp.t = p[j];
if (seeable(p[i], p[j], i, j) && judge(p[i], p[j])) {
double len = temp.getdis();
dis[i][j] = dis[j][i] = temp.getdis();
}
}
dis[0][1] = dis[1][0] = dis[0][2] = dis[2][0] =
dis[T][cnt] = dis[cnt][T] = dis[T][cnt - 1] = dis[cnt - 1][T] = 0;
dijkstra();
printf("%.10lf\n",dist[T]);
}
int main(){
init();
work();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: