3856. 【NOIP2014八校联考第3场第1试10.4】规避(path)

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。

Solution

对于在凸多边形上的点,一定是绕着多边形的边走最优,对于两个相邻的节点连上边,之后,对于两个多边形上的点,判断这条线段是否与另一个多边形相交,方法是枚举异于两个点所在多边形的多边形的两个不相邻节点,再求出两条线段所在直线的解析式,判断交点是否在两条线段上即可,注意判相交时,不能用“直线上方和下方都有同一个多边形的点经过”,因为有平行于x轴的直线这种情况,同时这种情况也要特判一下。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define I int
#define ll long long
#define db double
#define F(i,a,b) for(I i=a;i<=b;i++)
#define Fd(i,a,b) for(I i=a;i>=b;i--)
#define mem(a,b) memset(a,b,sizeof(a))
#define N 310
using namespace std;
void rd(I &x){
	x=0;I w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=w;
}
I n,m,c[N],cnt,lf,rg,bz,d[N*N],S,T;
db w[N*N],ks,bs,g[N][N];
struct node{I x,y;}a[N];
struct ft{I l,r;}b[N];
ll sqr(ll x){return x*x;}
db dis(I x,I y){
	db st=sqr((ll)a[x].x-a[y].x)+sqr((ll)a[x].y-a[y].y);
	return (db)sqrt(st);
}
void A(I x,I y,db z){g[x][y]=min(g[x][y],z);}
db slp(I x,I y){return (db)(a[x].y-a[y].y)/(db)(a[x].x-a[y].x);}
I main(){
	rd(n);
	F(i,1,n){
		rd(m);b[i]=ft{cnt+1,cnt+m};
		F(j,1,m){
			rd(a[++cnt].x),rd(a[cnt].y);
			c[cnt]=i;
		}
	}
	mem(g,127);
	F(k,1,n){
		lf=b[k].l,rg=b[k].r;
		F(i,lf,rg-1){A(i,i+1,dis(i,i+1)),A(i+1,i,dis(i+1,i));}
		A(lf,rg,dis(lf,rg)),A(rg,lf,dis(lf,rg));
	}
	F(i,1,cnt){
		F(j,i+1,cnt) if(c[i]!=c[j]){
			ks=slp(i,j),bs=(db)a[i].y-(db)a[i].x*ks,bz=1;
			I lx=min(a[i].x,a[j].x),rx=a[i].x+a[j].x-lx;
			F(k,1,n){
				lf=b[k].l,rg=b[k].r;
				F(l,lf,rg) if(l!=i&&l!=j){
					F(l2,lf,rg) if(l2!=i&&l2!=j&&l2!=l){
						db k2=slp(l,l2),b2=(db)a[l].y-(db)a[l].x*k2;
						db x=(b2-bs)/(ks-k2);
						I lx2=min(a[l].x,a[l2].x),rx2=a[l].x+a[l2].x-lx2;
						if(x>=lx2&&x<=rx2&&x>=lx&&x<=rx){bz=0;break;}
					}
				}
				if(!bz) break;
			}
			if(bz){A(i,j,dis(i,j)),A(j,i,dis(j,i));}
		} 
	}
	rd(S),rd(T);
	F(k,1,cnt){
		F(i,1,cnt){
			F(j,1,cnt) if(i!=j) g[i][j]=min(g[i][j],g[i][k]+g[j][k]);
		}
	}
	printf("%.04lf\n",g[S][T]);
	return 0;
}
发布了199 篇原创文章 · 获赞 201 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zsjzliziyang/article/details/104031044