URAL 1750 Pakhom and the Gully 计算几何+floyd

题目链接:点击打开链接

gg。。。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <math.h>
using namespace std;
#define ll int
#define point Point
const double eps = 1e-8;
const double PI = acos(-1.0);
double ABS(double x){return x>0?x:-x;}
int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x<0)return -1;
	return 1;
}
struct Point
{
	double x, y;
	void put(){printf("%.0f,%.0f\n",x,y);}
	Point(){}
	Point(double _x, double _y){
		x = _x; y = _y;
	}
	Point operator - (const Point & b)const{
		return Point(x-b.x, y-b.y);
	}
	double operator ^ (const Point &b) const{
		return x*b.y - y*b.x;
	}
	double operator *(const Point &b) const{
		return x*b.x + y*b.y;
	}
	void transXY(double B){
		double tx = x, ty = y;
		x = tx*cos(B) - ty*sin(B);
		y = tx*sin(B) + ty*cos(B);
	}
};
double dist(point a,point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
struct Line
{
	Point s,e;
	double len(){return dist(s,e);}
	Line(){}
	Line(Point _s, Point _e)
	{
		s = _s; e = _e;
	}
	pair<int,Point> operator & (const Line &b) const{
		Point res = s;
		if(sgn((s-e) ^ (b.s-b.e)) == 0)
		{
			if(sgn((s-b.e) ^ (b.s-b.e)) == 0)
				return make_pair(0,res);
			else return make_pair(1,res);
		}
		double t = ((s-b.s) ^ (b.s-b.e)) / ((s-e)^(b.s-b.e));
		res.x += (e.x - s.x) *t;
		res.y += (e.y - s.y) *t;
		return make_pair(2, res);
	}
};
double cross(point a, point b, point c) {
	return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x);
}
bool intersect(Line l1, Line l2) {
	return
		max(l1.s.x, l1.e.x) > (min(l2.s.x, l2.e.x)-eps) &&
		max(l2.s.x, l2.e.x) > (min(l1.s.x, l1.e.x)-eps) &&
		max(l1.s.y, l1.e.y) > (min(l2.s.y, l2.e.y)-eps) &&
		max(l2.s.y, l2.e.y) > (min(l1.s.y, l1.e.y)-eps) &&
		(cross(l2.s, l1.e, l1.s) * cross(l1.e, l2.e, l1.s) > -eps) &&
		(cross(l1.s, l2.e, l2.s) * cross(l2.e, l1.e, l2.s) > -eps);
}
bool online(Line l, point P) {
	return (fabs(cross(l.e, P, l.s)) < eps) &&
		((((P.x > l.s.x - eps) && (P.x < l.e.x + eps)) || ((P.x > l.e.x - eps) && (P.x < l.s.x+eps)))&&
		(((P.y > l.s.y - eps) && (P.y < l.e.y + eps)) || ((P.y > l.e.y - eps) && (P.y < l.s.y +eps))));
}
bool inter(Line u, Line v){
	return ((intersect(u, v)) && (!online(u, v.s)) && (!online(u, v.e)) && (!online(v, u.s)) && (!online(v, u.e)));
}
point S, T, A, B, C;
Line AB, BC, ST, AC, SA, SB, SC, TA, TB, TC;
double ans;
bool ok(Line x){
	if(inter(x, AB))return false;
	if(inter(x, BC))return false;
	return true;
}
double d[5][5];
void addedge()
{
	for (int i=0;i<5;i++)
		for (int j=0;j<5;j++)
		{
			if (i==j) d[i][j]=0;
			else d[i][j]=1e8;
		}

		if (!inter(SA, BC))
		{
			d[0][1]=d[1][0]=min(d[0][1],dist(S,A));
		}
		//d[0][2]=d[2][0]=min(d[0][2],dis(S,B));

		d[1][2]=d[2][1]=min(d[1][2],dist(A,B));
		d[1][3]=d[3][1]=min(d[1][3],dist(A,C));
		d[2][3]=d[3][2]=min(d[2][3],dist(B,C));

		if (!inter(SC,AB))
		{
			d[0][3]=d[3][0]=min(d[0][3],dist(S,C));
		}

		if (!intersect(ST,AB) && !intersect(ST,BC))
		{
			d[0][4]=d[4][0]=min(d[0][4],dist(S,T));
		}
		//printf("1->4 %d\n",is_inter(A,T,B,C));
		if (!inter(TA,BC))
		{
			d[1][4]=d[4][1]=min(d[1][4],dist(A,T));
		}

		if (cross(B,A,T)*cross(B,C,T)>-eps)
		{
			d[2][4]=d[4][2]=min(d[2][4],dist(B,T));
		}

		if (cross(S,A,B)*cross(S,C,B)>-eps)
		{
			d[0][2]=d[2][0]=min(d[0][2],dist(S,B));
		}

		if (!inter(TC,AB))
		{
			d[3][4]=d[4][3]=min(d[3][4],dist(C,T));
		}

}
int main(){
	int i, j, k, cas;scanf("%d",&cas);
	while(cas--) {
		scanf("%lf %lf", &S.x, &S.y);
		scanf("%lf %lf", &T.x, &T.y);
		scanf("%lf %lf", &A.x, &A.y);
		scanf("%lf %lf", &B.x, &B.y);
		scanf("%lf %lf", &C.x, &C.y);
		AB = Line(A,B); BC = Line(B,C); ST = Line(S,T); AC = Line(A,C);
		SA = Line(S,A); SB = Line(S,B); SC = Line(S,C);
		TA = Line(T,A); TB = Line(T,B); TC = Line(T,C);
		addedge();
		for(i = 0; i < 5; i++)
			for(j = 0; j < 5; j++)
				for(k = 0; k < 5; k++)
					d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
		printf("%.8f\n", d[0][4]);
	}
	return 0;
}
/*


*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值