POJ - 1556 【計算幾何 + 最短路】
The Doors
題意 : 給出一個房間,大小為10×10,起點在(0,5),終點在(10,5),房間中有若干堵牆,問從起點到終點的最短路徑。
題解 : 列舉每兩點,如果這兩個點構成的線段沒有與房間中的任何一線段相交,那麼就建一條邊,所有邊建完之後跑一邊迪傑斯特拉就好了。
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
using namespace std;
const double pi = acos((double)(-1));
#define inf 0x3f3f3f3f
#define ll long long
#define eps 1e-8
const int maxn = 110;
const int mod = 1e9 + 7;
int sgn(double x){
if(fabs(x) < eps) return 0;
else return x < 0?-1:1;
}
struct Point{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
Point operator + (Point B){return Point(x + B.x,y + B.y);}
Point operator - (Point B){return Point(x - B.x,y - B.y);}
Point operator * (double k){return Point(x*k,y*k);}
Point operator / (double k){return Point(x/k,y/k);}
bool operator == (Point B){return sgn(x - B.x) == 0 && sgn(y - B.y) == 0;}
}P[maxn];
typedef Point Vector;
struct Line{
Point p1,p2;
Line(){}
Line(Point p1,Point p2):p1(p1),p2(p2){}
Line(Point p,double angle){ //y = kx + b
p1 = p;
if(sgn(angle - pi/2) == 0){p2 = (p1 + Point(0,1));}
else {p2 = (p1 + Point(1,tan(angle)));}
}
Line(double a,double b,double c){ //ax + by + c = 0
if(sgn(a) == 0){
p1 = Point(0, -c/b);
p2 = Point(1, -c/b);
}
else if(sgn(b) == 0){
p1 = Point(-c/a,0);
p2 = Point(-c/a,1);
}
else{
p1 = Point(0,-c/b);
p2 = Point(1,(-c - a)/b);
}
}
}L[maxn];
typedef Line Segment;
double Dist(Point A,Point B){
return sqrt((A.x - B.x)*(A.x - B.x) + (A.y - B.y)*(A.y - B.y));
}
double Cross(Vector A,Vector B){return A.x*B.y - A.y*B.x;}
bool Cross_segment(Point a, Point b, Point c, Point d){
double c1 = Cross(b - a, c - a), c2 = Cross(b - a, d - a);
double d1 = Cross(d - c, a - c), d2 = Cross(d - c, b - c);
return sgn(c1) * sgn(c2) < 0 && sgn(d1) * sgn(d2) < 0;
}
int n;
double x, y;
bool judge(Line v){
for(int k = 1; k <= 6 * n; k+=2){
if(Cross_segment(L[1].p1, L[1].p2, P[k], P[k + 1]) == 1) return false;
}
return true;
}
double d[maxn];
int vis[maxn];
struct node{
int to;
double w;
node(int to_,double w_){
to = to_,w = w_;
}
};
vector<node>v[maxn];
void Dij(){
d[0] = 0;
while(1){
double min1=999999.0 ;
int z = -1;
for(int i = 0;i < 6 * n + 1; i++){
if(d[i] < min1 && !vis[i]){
min1 = d[i];
z = i;
}
}
if(z == -1) break;
vis[z] = 1;
for(int i = 0;i < v[z].size(); i++){
int vv = v[z][i].to;
double dis = v[z][i].w;
if(d[vv] > dis + d[z]) d[vv] = dis + d[z];
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
while(cin>>n){
if(n == -1) break;
for(int i = 0;i <= 6 * n + 1;i++){
v[i].clear();
vis[i]=0;
d[i]=99999.0;
}
P[0].x = 0;
P[0].y = 5;
for(int i = 1; i <= n; i++){
cin>>x;
P[(i - 1) * 6 + 1].x = x;
P[(i - 1) * 6 + 1].y = 0;
for(int j = 2; j <= 5; j++){
cin>>y;
P[(i - 1) * 6 + j].x = x;
P[(i - 1) * 6 + j].y = y;
}
P[(i - 1) * 6 + 6].x = x;
P[(i - 1) * 6 + 6].y = 10;
}
P[6 * n + 1].x = 10;
P[6 * n + 1].y = 5; //true
for(int i = 0; i < 6 * n + 1; i++){
if((i % 6 == 1 || i % 6 == 0) && i != 0) continue;
for(int j = i + 1; j <= 6 * n + 1; j++){
if((j % 6 == 1 || j % 6 == 0) && j != 6 * n + 1) continue;
L[1].p1.x = P[i].x;
L[1].p1.y = P[i].y;
L[1].p2.x = P[j].x;
L[1].p2.y = P[j].y;
if(judge(L[1])){
double dist = Dist(P[i] ,P[j]);
v[i].push_back(node(j, dist));
}
}
}
Dij();
cout<<fixed<<setprecision(2)<<d[6 * n + 1]<<endl;
}
return 0;
}
相關文章
- POJ 1556 The Doors(Dijkstra+計算幾何)
- An Easy Problem?! POJ 2826 計算幾何
- POJ 2991 Crane(線段樹+計算幾何)
- POJ 1113 Wall(思維 計算幾何 數學)
- 計算幾何
- POJ 1127-Jack Straws(計算幾何 線段相交)
- POJ 1039-Pipe(計算幾何-線段相交、求交點)
- HDU 4606 Occupy Cities (計算幾何+最短路+最小路徑覆蓋)
- 計算幾何:模板
- 計算幾何模板
- [筆記] 計算幾何筆記
- 【計算幾何】向量表示
- 【總結】計算幾何模板
- 二維計算幾何模板
- 【計算幾何】線段相交
- 三維計算幾何模板
- Something about 計算幾何
- 計算幾何 —— 二維幾何基礎 —— 距離度量方法
- 邊緣計算、霧計算、雲端計算區別幾何?
- 【學習筆記】計算幾何筆記
- 計算幾何_向量的實現
- 【計算幾何】多邊形交集
- 計算幾何——平面最近點對
- POJ 3335-Rotating Scoreboard(計算幾何-半平面交順時針模板)
- POJ 1584-A Round Peg in a Ground Hole(計算幾何-凸包、點到線段距離)
- 計算幾何常用的函式/方法函式
- POJ 1408-Fishnet(計算幾何-根據交點求多邊形面積)
- BNUOJ 12887 isumi(計算幾何+最大流)
- SGU 124 Broken line(計算幾何)
- 【計算幾何】Triangles HUST 1607
- 【計算幾何】多邊形點集排序排序
- POJ 2240 Arbitrage(Floyd最短路)
- C++計算幾何演算法大全C++演算法
- 【計算幾何】點在多邊形內部
- POJ 3130-How I Mathematician Wonder What You Are!(計算幾何-星形-半平面交逆時針模板)
- 二維幾何常用運算
- SGU 120 SGU 228 Archipelago(計算幾何)Go
- 計算機視覺—圖片幾何變換(2)計算機視覺