HDU3694 Fermat Point in Quadrangle 多边形费马点结论

Posted legend_PawN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU3694 Fermat Point in Quadrangle 多边形费马点结论相关的知识,希望对你有一定的参考价值。

HDU3694
前面说了一大推都没什么用,最后是求四边形的一个fermat点。
多边形的fermat点是欧拉平面上的一个点到多边形每个点的距离之和最小的点
四边形的fermat点在四个顶点与对角线交点值5个点中较小的那个,直接套模板计算取最小值即可
在判断多边形的对角线时小小用了一下极角排序
AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
const double eps=1e-8;
using namespace std;
int sgn(double x)
    if(fabs(x)<eps)
        return 0;
    return x>0 ?1 :-1;

struct point
    double x,y;
    point() 
    point(double _x,double _y)
        x=_x;
        y=_y;
    
;
point p[10];
point operator - (point A,point B)
    return point(A.x-B.x,A.y-B.y);

int operator ^ (point A,point B)
    return A.x*B.y-A.y*B.x;

int operator * (point A,point B)
    return A.x*B.x+A.y*B.y;

bool operator < (point A,point B)
    return A.x<B.x || A.x==B.x && A.y<B.y;

bool operator == (point a,point b)
    return sgn(a.x-b.x)==0 && sgn(a.y-b.y)==0;

double dis(point a,point b)
    return hypot(a.x-b.x,a.y-b.y);

bool cmp(point a,point b) //极角排序函数
        int d=sgn((a-p[0])^(b-p[0]));
        if(d==0&&sgn(dis(a,p[0])-dis(b,p[0])) < 0 || d>0)//共线时取较近的点
            return true;
        return false;

struct line
    point s,e;
    line() 
    line (point _s,point _e)
        s=_s;
        e=_e;
    
    point crosspoint(line v)
        double a1=(v.e-v.s)^(s-v.s);
        double a2=(v.e-v.s)^(e-v.s);
        return point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
    
;
double solve()
    for(int i=0;i<4;i++)
        if(p[i]<p[0])
            swap(p[i],p[0]);
    sort(p+1,p+4,cmp);
    double m=50000.0,tmp;
    for(int i=0;i<4;i++)
        tmp=dis(p[i],p[(i+1)%4])+dis(p[i],p[(i+2)%4])+dis(p[i],p[(i+3)%4]);
        if(tmp<m)
            m=tmp;
    
    line l1=line(p[0],p[2]);
    line l2=line(p[1],p[3]);
    point f=l1.crosspoint(l2);
    tmp=dis(f,p[0])+dis(f,p[1])+dis(f,p[2])+dis(f,p[3]);
    if(tmp<m)
        m=tmp;
    return m;

int main()
    //freopen("e.txt","r",stdin);
    while(cin>>p[0].x>>p[0].y>>p[1].x>>p[1].y>>p[2].x>>p[2].y>>p[3].x>>p[3].y)
        if(p[0].x==-1 && p[0].y==-1 && p[1].x==-1 && p[1].y==-1 && p[2].x==-1 && p[2].y==-1 && p[3].x==-1 && p[3].y==-1)
            break;
        double ans=solve();
        printf("%.4lf\\n",ans);
    
    return 0;

以上是关于HDU3694 Fermat Point in Quadrangle 多边形费马点结论的主要内容,如果未能解决你的问题,请参考以下文章

poj3694(lca + tarjan求桥模板)

HDU5907 Find Q 数学

HDU 6623 Minimal Power of Prime(思维)题解

POJ 3694 Network (tarjan + LCA)

Q - N! HDU - 1042

POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)