zoukankan      html  css  js  c++  java
  • [计算几何][spfa] Jzoj P3856 规避

    Description

    2014年7月17日,马来西亚航空MH17班机执飞阿姆斯特丹史基浦机场飞往吉隆坡国际机场航线时,在乌克兰靠近俄罗斯边界33,000英尺高空疑受到9K37山毛榉地对空导弹击落坠毁。事件发生后,汉莎航空、法国航空、土耳其航空、俄罗斯洲际航空、达美航空、英国航空、俄罗斯航空、印度航空、捷特航空和荷兰皇家航空开始禁止班机进入乌克兰东部或全境领空范围。美国航空公司的班机禁止在乌克兰境内飞行,同时UTair航空、意大利航空和维珍航空也宣布他们的班机将会重新规划航行的路线。英国交通部已经要求该国的班机不要进入乌克兰领空范围。中国民用航空局已要求国内航空公司所有飞越乌克兰的航班绕飞。
    作为相关负责人,你需要根据实际情况规划航线规避不安全地区,包括战争区域、危险天气、火山灰和外星人入侵……等。每个不安全区域被标记为一个凸多边形,每个凸多边形相离,你需要规划一条从指定起点到指定终点的航线,要求航线不得进入不安全区域,输出它的最短长度。为了你的方便,起点和终点都是多边形的顶点。
     

    Input

    第一行一个整数N表示不安全区域的数目。
    接下来共N组描述,分别对应每个区域,首先输入一个空行,接下来第一个数num表示该区域顶点数,接下来共num个整数对按逆时针方向描述每个顶点。
    在描述起点终点前输入空行,然后两个整数S和T描述起点和终点。起点为之前读入的总第S个顶点,终点同理。

    Output

    一行共一个数表示最短长度,保留4位小数。
     

    Sample Input

    2
     
    4
    0 0
    1 0
    1 1
    0 1
     
    4
    2 2
    3 2
    3 3
    2 3
     
    1 7

    Sample Output

    4.8284
     

    Data Constraint

    M表示顶点总数   
    对于10%的数据,N=1。
    对于30%的数据,N<=2。
    对于50%的数据,N<=10,M<=50。
    对于100%的数据,N<=100,M<=300,-32768<=读入的坐标<=32767。

    题解

    • 题目大意:在一个平面上有n个凸边形障碍物,问在不与障碍物相交的情况下,从起点到总点的最短距离
    • 看到这题,我们显然可以发现,一条最短路径应该是贴着凸边形走的,也就是在凸边形的边上走
    • 那么,我们就可以预处理出凸边形所有顶点两两的距离,然后要判断这条边有没有和凸边形相交
    • 怎么判断呢,这就是好问题
    • 每次判断是否与多边形隔一个点的两个点连成的弦判相交即可
    • 那么最后怎么求答案呢,其实随便跑个最短路算法就好了

    代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cmath>
     7 #define sqr(x) ((x)*1ll*(x))
     8 #define N 310
     9 #define M 180010
    10 #define inf 1000000000.0 
    11 #define fi first
    12 #define se second
    13 using namespace std;
    14 typedef pair<int,int> edge;
    15 struct Edge{ int to,from; double v; }e[M];
    16 struct node{ edge x,y; }E[M];
    17 int n,cnt,num[N],head[N],tot,k,s,t,l,vis[N];
    18 double dis[N];
    19 edge a[N];
    20 double calc(edge a,edge b) { return sqrt(sqr(a.fi-b.fi)+sqr(a.se-b.se)); }
    21 void insert(int x,int y,double v) 
    22 { 
    23     e[++cnt].to=y,e[cnt].from=head[x],e[cnt].v=v,head[x]=cnt; 
    24     e[++cnt].to=x,e[cnt].from=head[y],e[cnt].v=v,head[y]=cnt; 
    25 }
    26 double cross(edge a,edge b,edge c) { return (a.fi-b.fi)*1.0*(a.se-c.se)-(a.se-b.se)*1.0*(a.fi-c.fi);}
    27 bool checkcross(node a,node b){ return cross(a.x,a.y,b.x)*cross(a.x,a.y,b.y)<=1e-5&&cross(b.x,b.y,a.x)*cross(b.x,b.y,a.y)<=1e-5; }
    28 bool check(edge a,edge b)
    29 {
    30     for (int i=1;i<=tot;i++)
    31     {
    32         if (E[i].x==a||E[i].y==b||E[i].x==b||E[i].y==a) continue;
    33         if (checkcross((node){a,b},E[i])) return 0;
    34     }
    35     return 1;
    36 }
    37 double spfa()
    38 {
    39     queue<int> Q;
    40     for (int i=1;i<=k;i++) dis[i]=inf;
    41     dis[s]=0,Q.push(s);
    42     while (!Q.empty())
    43     {
    44         int x=Q.front(); Q.pop(),vis[x]=0;
    45         for (int i=head[x];i;i=e[i].from)
    46             if (dis[e[i].to]>dis[x]+e[i].v)
    47             {
    48                 dis[e[i].to]=dis[x]+e[i].v;
    49                 if (!vis[e[i].to]) vis[e[i].to]=1,Q.push(e[i].to);
    50             }
    51     }
    52     return dis[t];
    53 }
    54 int main()
    55 {
    56     scanf("%d",&n);
    57     for (int i=1;i<=n;i++)
    58     {
    59         scanf("%d",&num[i]),num[i]+=k;
    60         for (int j=k+1;j<=num[i];j++)
    61         {
    62             scanf("%d%d",&a[j].fi,&a[j].se);
    63             if (j-k!=1) insert(j,j-1,calc(a[j],a[j-1])),E[++tot]=(node){a[j],a[j-1]};
    64         }
    65         insert(k+1,num[i],calc(a[k+1],a[num[i]])),E[++tot]=(node){a[k+1],a[num[i]]},k=num[i];
    66     }
    67     for (int i=1;i<=k;i++)
    68     {
    69         while (i>num[l]) l++;
    70         for (int j=i+1;j<=k;j++)
    71         {
    72             if (num[l-1]<j&&j<=num[l]) continue;
    73             if (check(a[i],a[j])) insert(i,j,calc(a[i],a[j]));
    74         }
    75     }
    76     scanf("%d%d",&s,&t),printf("%.4lf",spfa());
    77 }
  • 相关阅读:
    arcgis10.2转shp文件中文乱码问题解决方案
    Android Context作为参数传递this
    andriod inputbox
    andriod inputType
    《ArcGIS Runtime SDK for Android开发笔记》——(5)、基于Android Studio构建ArcGIS Android开发环境(离线部署)(转)
    终于理解了什么是LGPL
    产品经理如何与强势的技术沟通? 技术比较有资历,会以技术无法实现等方面的原因拒绝处理产品提出的需求。 你们是否遇到这样的技术? 产品懂技术的话,是不是会好一些,因为可以和技术说“行话”了,并且产品懂技术就不会被忽悠了。
    Core Dump总结
    LIBRARY_PATH是编译时候用的,LD_LIBRARY_PATH是程序运行是使用的
    如何禁止C++默认成员函数
  • 原文地址:https://www.cnblogs.com/Comfortable/p/10302312.html
Copyright © 2011-2022 走看看