Poj 1556 The Doors
来源:互联网 发布:最新抢火车票软件 编辑:程序博客网 时间:2024/05/16 09:47
题意:
求穿越对角线为(0,0,10,10)矩形的(0,5)到(10,5)的最短路径
在矩形里面存在竖直的墙体, 没个墙上在上面开了两个口:用5个参数描述x,y1, y2, y3, y4
x为墙的x坐标,y1-y4为从下到上的缺口端点
方法: 以所有墙的墙角(缺口处)和起始两点为顶点,建立无向图。
建图过程中需要判断两条线段是否相交。
=》知识点:最短路 + 线段相交判定。 最短路用Dijkstar即可
判断线段相交: 利用叉积(相乘大于零逆时针)
1.如果Line1的两个顶点在Line2的同侧,则不相交
2.若1不成立,判断Line2的两个顶点在Line1的同侧,则不想交
求穿越对角线为(0,0,10,10)矩形的(0,5)到(10,5)的最短路径
在矩形里面存在竖直的墙体, 没个墙上在上面开了两个口:用5个参数描述x,y1, y2, y3, y4
x为墙的x坐标,y1-y4为从下到上的缺口端点
方法: 以所有墙的墙角(缺口处)和起始两点为顶点,建立无向图。
建图过程中需要判断两条线段是否相交。
=》知识点:最短路 + 线段相交判定。 最短路用Dijkstar即可
判断线段相交: 利用叉积(相乘大于零逆时针)
1.如果Line1的两个顶点在Line2的同侧,则不相交
2.若1不成立,判断Line2的两个顶点在Line1的同侧,则不想交
3.若2不成立,则线段相交
#include <cstdio>#include <cstring>#include <string>#include <string>#include <cmath>#include <algorithm>#include <vector>#include <queue>#define MAX 10005#define INF 100000000#define PI acos(-1.0)#include <iostream>using namespace std;//0ms 1Ystruct Vector2d{ double x, y; Vector2d(){} Vector2d(double xx, double yy){ x = xx; y = yy;} Vector2d(const Vector2d &v){x = v.x; y = v.y;}; double crossMul(const Vector2d &vec)const{ //Vector2d ans((x * vec.y), (y * vec.x)); return (x * vec.y) - (y * vec.x); } Vector2d sub(const Vector2d &point)const{ Vector2d ans(x - point.x, y - point.y); return ans; } double getLength()const{ return sqrt(x * x + y * y); } void output(){ cout<<x<<" "<<y<<endl; }};struct Line{ Vector2d p1; Vector2d p2; Line(){} Line(const Vector2d &mp1, const Vector2d &mp2):p1(mp1), p2(mp2){} bool isInsect(const Line &line)const{ Vector2d va = line.p1.sub(p1), vb = line.p1.sub(p2); double cmRes1 = va.crossMul(vb); va = line.p2.sub(p1); vb = line.p2.sub(p2); double cmRes2 = va.crossMul(vb); if(cmRes1 == 0 || cmRes2 == 0)return true; if( (cmRes1 > 0 && cmRes2 > 0) || (cmRes1 < 0 && cmRes2 < 0) )///同号不想交 return false; va = p1.sub(line.p1); vb = p1.sub(line.p2 ); cmRes1 = va.crossMul(vb); va = p2.sub(line.p1); vb = p2.sub(line.p2); cmRes2 = va.crossMul(vb); if(cmRes1 == 0 || cmRes2 == 0)return true; if( (cmRes1 > 0 && cmRes2 > 0) || (cmRes1 < 0 && cmRes2 < 0) )///同号不相交 return false; return true; } double getLength(){ return p1.sub(p2).getLength(); }};struct Wall{ double x, y1, y2, y3, y4; void input(){ cin>>x>>y1>>y2>>y3>>y4; } Vector2d getPoint(int index)const{ Vector2d vec; vec.x = x; switch(index){ case 1: vec.y = y1;break; case 2: vec.y = y2; break; case 3: vec.y = y3; break; case 4: vec.y = y4; break; default: puts("index outof bounds"); break; } return vec; }}walls[MAX];struct Edge{ int pos, next; double val;}edge[MAX * 2];int N, vN;int head[MAX], e;Vector2d start(0, 5);Vector2d end(10, 5);bool isCanLink(const int &ii, const int &i, Vector2d &pNow , Vector2d &pTest);void insert(int a, int b, double val){ edge[e].next = head[a]; edge[e].pos = b; edge[e].val = val; head[a] = e++;}void showMap(){ for(int i = 0; i < vN; i++){ int next = head[i], pos; printf("head : %d\n", i); while(next != -1){ pos = edge[next].pos; cout<<pos<<"->"<<edge[next].val<<":::"; next = edge[next].next; }cout<<endl; }}void init(){ e = 0; memset(head, -1, sizeof(head)); vN = N * 4 + 2;//0 - (vN - 1) for(int i = 0; i < N; i++){ walls[i].input(); }//end input}void makeMap(){//O(vN^2) Vector2d pNow, pTest; Line line; for(int i= 0;i < N; i++){ for(int j = 1; j <= 4; j++ ){ pNow = walls[i].getPoint(j);// puts("pNow get"); for(int ii = i - 1; ii >= 0; ii--){ for(int jj = 1; jj <= 4; jj++){ pTest = walls[ii].getPoint(jj);// puts("pTest get"); if(isCanLink(ii, i, pNow, pTest)){ int a = i * 4 + j, b = ii * 4 + jj; line.p1 = pNow; line.p2 = pTest; double val = line.getLength(); insert(a, b, val); insert(b, a, val); } } }//之前检测完毕 line.p1 = pNow; line.p2 = start; if(isCanLink(-1, i, pNow, start)){ int a = i * 4 + j, b = 0; double val = line.getLength(); insert(a, b, val); insert(b, a, val); } } }//全部线段之前检测完毕// puts("end point left"); pNow = end; for(int ii = N - 1; ii >= 0; ii--){ for(int jj = 1; jj <= 4; jj++){ pTest = walls[ii].getPoint(jj); if(isCanLink(ii, N, pNow, pTest)){ int a = ii * 4 + jj, b = vN - 1; line.p1 = pNow; line.p2 = pTest; double val = line.getLength(); insert(a, b, val); insert(b, a, val); } } }//最后之前一点检测完毕 if(isCanLink(-1, N, start, end)){ int a = 0, b = vN - 1; double val = start.sub(end).getLength(); insert(a, b, val); insert(b, a, val); }//全部点处理完毕}bool isCanLink(const int &ii, const int &i, Vector2d &pNow , Vector2d &pTest){ Line line1(pNow, pTest), line2;// puts("judge : ");// pNow.output();pTest.output(); for(int ptr = i - 1; ptr > ii ; ptr --){ int canPass = 2; for(int j = 1; j <= 4; j+= 2){ line2.p1 = walls[ptr].getPoint(j); line2.p2 = walls[ptr].getPoint(j + 1); if(!line1.isInsect(line2)){//不过缺口线段则不可连接 canPass --;// printf("cannot Insect at %d: %d with lines\n", ptr, j);// line1.p1.output();line1.p2.output();// line2.p1.output();line2.p2.output();// puts("end"); } } if(canPass == 0){ return false; } }// puts("can link"); return true;}void dijkstra(){ double d[MAX]; bool v[MAX]; for(int i = 0; i < vN; i++){ d[i] = INF; v[i] = false; } d[0] = 0; double min_d; int index; for(int i = 0; i < vN - 1; i++){ min_d = INF; index = -1; for(int j = 0; j < vN; j++){ if(!v[j] && min_d > d[j]){ min_d = d[j]; index = j; } } if(index != -1){ v[index] = true; int next = head[index], pos; while(next != -1){ pos = edge[next].pos; if(!v[pos]){ double dist = d[index] + edge[next].val; if(d[pos] > dist)d[pos] = dist; } next = edge[next].next; } } } printf("%.2f\n", d[vN -1]);}int main(){ while(cin>>N, N != -1){ init();// puts("init end"); makeMap();// showMap();// puts("makeMap end"); dijkstra(); } return 0;}
- poj 1556 The Doors
- poj 1556 The Doors
- POJ 1556 The Doors
- poj 1556 The Doors
- poj 1556 The Doors
- Poj 1556 The Doors
- POJ 1556 The Doors
- poj 1556 The Doors
- poj 1556 The Doors
- poj 1556 The Doors
- POJ 1556 The Doors
- poj 1556The Doors
- POJ 1556 The Doors
- poj 1556 The Doors
- POJ 1556 The Doors 笔记
- zoj 1721 || poj 1556 The Doors
- POJ 1556 The Doors(Dijkstra+计算几何)
- POJ 1556 The Doors (线段相交+Dijkstra)
- Linux下SVN客户端的使用方法
- Leetcode: Binary Tree Zigzag Level Order Traversal
- 心情历练 技术沉淀 生活积淀
- POJ1151(求矩阵的并面积) 离散化
- Struts2.x中获取request,response,session的方式
- Poj 1556 The Doors
- C# 读取Excel文件
- ffmepg 指定网络连接模式UDP还是TCP
- struts2的拦截器(3):通过实现Interceptor接口定义自己的拦截器
- 分布式数据库 HBase
- 开始写点东西
- VLC搭建RTSP服务器的过程
- Hadoop - 你不得不了解的大数据工具
- 打造vim IDE环境,管理大型项目