POJ1556

题目大意:比较明显的题目,在一个房间中有几堵墙,直着走,问你从(0,5)到(10,5)的最短路是多少

求最短路问题,唯一变化的就是边的获取,需要我们获取边,这就需要判断我们想要走的这条边会不会经过墙

所以创建点集,线段集合

#include <iostream>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <iomanip>
#define eps 1e-10
#define inf 0x3f3f3f3f
#define equal(a,b) fabs((a) - (b)) < eps
using namespace std;
const int maxn = 200;
int pnum,lnum;
struct Point
{
double x,y;
Point(double x = 0.0,double y = 0.0):x(x),y(y){} Point operator - (Point p){return Point(x-p.x,y-p.y);} }ps[maxn];
struct segment
{
Point p1,p2;
segment(Point p1 = Point(0.0,0.0),Point p2 = Point(0.0,0.0)):p1(p1),p2(p2){}
}ls[maxn];
//存储线段和点~~

事先也要准备好最短路的东西

double mp[maxn][maxn];
double dis[maxn];
int vis[maxn];
int main()
{
int n;
double x,y1,y2,y3,y4;
while(~scanf("%d",&n),n != -1)
{
init();
ps[pnum++] = Point(0,5);
for(int i = 0;i < n;i++)
{
scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
ps[pnum++] = Point(x,y1);
ps[pnum++] = Point(x,y2);
ps[pnum++] = Point(x,y3);
ps[pnum++] = Point(x,y4);
ls[lnum++] = segment(Point(x,0),Point(x,y1));
ls[lnum++] = segment(Point(x,y2),Point(x,y3));
ls[lnum++] = segment(Point(x,y4),Point(x,10));
}
ps[pnum] = Point(10,5);
for(int i = 0;i <= pnum;i++)
{
for(int j = 0;j <= pnum;j++)
{
if(i == j)mp[i][j] = 0.0;
else if(checkline(i,j))
{
mp[i][j] = getdis(i,j);
//printf("%d %d\n",i,j);
//cout<<mp[i][j]<<endl;
//cout<<mp[i][j]<<endl;
}
else mp[i][j] = inf * 1.0;
}
}
dijkscar(0,pnum);
cout << fixed << setprecision(2) << dis[pnum] << endl; }
return 0;
}

main函数中是输入点和线段至对应的集合中,然后去找合适的边填充mp二维数组,这是侯用到了线段相交的判断

bool intersect(int i,int j,int k)
{
if(cross(ps[i],ps[j],ls[k].p1) * cross(ps[i],ps[j],ls[k].p2) < -eps &&
cross(ls[k].p1,ls[k].p2,ps[i]) * cross(ls[k].p1,ls[k].p2,ps[j]) < -eps)return true;
return false;
}
bool checkline(int i,int j)
{
for(int k = 0;k < lnum;k++)
{
//printf("k = %d && i = %d && j = %d Point[i] = (%d,%d),Point[j] = (%d,%d),Segment = %d %d %d %d\n",k,i,
// j,(int)ps[i].x,(int)ps[i].y,(int)ps[j].x,(int)ps[j].y,(int)ls[k].p1.x,(int)ls[k].p1.y,(int)ls[k].p2.x,(int)ls[k].p2.y);
if(intersect(i,j,k))
return false;
}
return true;
}
double cross(Point p1,Point p2,Point p3)
{
Point a = p2 - p1;
Point b = p3 - p1;
return a.x * b.y - a.y * b.x;
}

线段是否相交,利用外积的方向判断,如果双方都符合一条线段的两个端点在另一条线段的两个端点时,就会相交

然后时常规的dijkscar算法

void dijkscar(int s,int n)
{
for(int i = 1;i <= n;i++)dis[i] = mp[s][i];
dis[s] = 0;
vis[s] = 1;
for(int i = 0;i <= n;i++)//优化次数
{
double minlen = inf * 1.0;
int net = 0;
for(int j = 1;j <= n;j++)
{
if(!vis[j] && dis[j] < minlen)
{
minlen = dis[j];
net = j;
}
//if(net == 0)break;
//if(minlen == inf * 1.0)break;
vis[net] = 1;
for(int j = 1;j <= n;j++)
{
if(dis[j] > dis[net] + mp[net][j])
{
dis[j] = dis[net] + mp[net][j];
}
}
}
} }

我犯的几个错误

dijkscar中if(net == 0)break;这句话导致我最短路判断失误,我目前也不知道什么原因

符合条件的边输入进mp数组,我以为只要输入单向向右的就行了所以一开始的for循环时i = 0 -> n - 1 + j = i + 1 - > n,结果发现,emm还是有特殊情况的,比如径直往上走的情况~~

POJ1556 最短路 + 线段相交问题的更多相关文章

  1. POJ 1556 The Doors【最短路+线段相交】

    思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...

  2. POJ1556 The Doors [线段相交 DP]

    The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8334   Accepted: 3218 Descrip ...

  3. 简单几何(线段相交+最短路) POJ 1556 The Doors

    题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...

  4. POJ_1556_The Doors_判断线段相交+最短路

    POJ_1556_The Doors_判断线段相交+最短路 Description You are to find the length of the shortest path through a ...

  5. HDU 4606 Occupy Cities ★(线段相交+二分+Floyd+最小路径覆盖)

    题意 有n个城市,m个边界线,p名士兵.现在士兵要按一定顺序攻占城市,但从一个城市到另一个城市的过程中不能穿过边界线.士兵有一个容量为K的背包装粮食,士兵到达一个城市可以选择攻占城市或者只是路过,如果 ...

  6. POJ 1066 Treasure Hunt (线段相交)

    题意:给你一个100*100的正方形,再给你n条线(墙),保证线段一定在正方形内且端点在正方形边界(外墙),最后给你一个正方形内的点(保证不再墙上) 告诉你墙之间(包括外墙)围成了一些小房间,在小房间 ...

  7. POJ 2653 Pick-up sticks (线段相交)

    题意:给你n条线段依次放到二维平面上,问最后有哪些没与前面的线段相交,即它是顶上的线段 题解:数据弱,正向纯模拟可过 但是有一个陷阱:如果我们从后面向前枚举,找与前面哪些相交,再删除前面那些相交的线段 ...

  8. HDU1086You can Solve a Geometry Problem too(判断线段相交)

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  9. POJ 2653 Pick-up sticks【线段相交】

    题意:n根木棍随意摆放在一个平面上,问放在最上面的木棍是哪些. 思路:线段相交,因为题目说最多有1000根在最上面.所以从后往前处理,直到木棍没了或者最上面的木棍的总数大于1000. #include ...

随机推荐

  1. 吴裕雄 实战PYTHON编程(6)

    import matplotlib.pyplot as plt plt.rcParams['font.sans-serif']=['Simhei']plt.rcParams['axes.unicode ...

  2. spring 中c3p0的优化配置

    jdbc.properties driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/testdb user=ro ...

  3. 网页信息抓取 Jsoup的不足之处 httpunit

    今天又遇到一个网页数据抓取的任务,给大家分享下. 说道网页信息抓取,相信Jsoup基本是首选的工具,完全的类JQuery操作,让人感觉很舒服.但是,今天我们就要说一说Jsoup的不足. 1.首先我们新 ...

  4. SpringCloud组件和概念介绍1

    一:什么是微服务(Microservice) 微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务.这些小的Web服务可以独立地编译及 ...

  5. Java8 lambda表达式语法 1

    本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人也是刚刚开始学习Java8,所以文中肯定有错误和理解偏差的地方,希望大家帮忙指出,我会持续修改和优化.本文是该系列的第一篇, ...

  6. Android logcat输出中文乱码

    使用adb的logcat 命令查看系统日志缓冲区的内容,会发现在CMD的界面面,直接输出的中文内容是乱码. 这个问题出现在使用logcat将日志直接打印在当前的DOS窗口的时候会出现:使用logcat ...

  7. How Many Answers Are Wrong(带权并查集)

    How Many Answers Are Wrong http://acm.hdu.edu.cn/showproblem.php?pid=3038 Time Limit: 2000/1000 MS ( ...

  8. ROS Learning-008 beginner_Tutorials ROS话题

    ROS Indigo beginner_Tutorials-07 ROS话题 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubuntu 14.04.4 LT ...

  9. NPOI创建doc

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  10. VC字符串处理整理

    场景: 1.在存储数据时有时接口需要合并字符串值,并以某些特殊字符来合并部分,到需要的时候再分割它.如一些数值,人名等. 2.C++有strtok,stringstream和find函数来实现分割.可 ...