car的旅行路线(floyd算法)

#include<cstdio>
#include<cmath>
#include<iostream>
#define	INF	1e20//有下划线的都是宏
#define	FOR(i,x)	for(int	i=1;i<=(x);i++)
#define	For(i,x,y)	for(int	i=(x);i<=(y);i++)
#define	pf(x)		(x)*(x)
#define	far(a,b)	sqrt(pf(d[a][0]-d[b][0])+pf(d[a][1]-d[b][1]))
#define	MAX(a,b,c)	max(a,max(b,c))
#define	IF(x,y)		if(x==y)
using namespace std;
int	d[5001][2],p[1001],c[5001];	//d[a][]表示机场a的坐标,  p[x]表示城市x的高速公路价格,  c[a]表示机场a所属的城市
int	A,B,t,sum;					//sum表示城市个数,  t为单位路程飞机的价格,  A,B分别为起点,终点
double g[5001][5001];
void readin(),cal(int),gz(int* ,int* ,int* ,int*),ycl();
double floyd();
int	main(){
	int	z;
	scanf("%d",&z);
	while(z--){
		readin();ycl();
		printf("%.1lf\n",floyd());//可换成四次dijskra,比一次floyd要略快
	}
}
void readin(){						//数据读入
	scanf("%d%d%d%d",&sum,&t,&A,&B);
	FOR(i,sum){						//用宏简化代码
		FOR(j,3){
			scanf("%d%d",&d[(i-1)*4+j][0],&d[(i-1)*4+j][1]);
			c[(i-1)*4+j]=i;
		}
		cal(i*4);					//求该城市第4个机场的坐标
		c[i*4]=i;
		scanf("%d",&p[i]);
	}
	sum*=4;							//此时sum表示机场的个数
}
void cal(int x){					//向量求坐标
	double k1=far(x-2,x-3),k2=far(x-1,x-3),k3=far(x-2,x-1),maxx=MAX(k1,k2,k3);//maxx是已知三点所构成的直角三角形的斜边长
	if(maxx==k1)gz(d[x-1],d[x-3],d[x-2],d[x]);				//判断直角顶点
	else if(maxx==k2)gz(d[x-2],d[x-1],d[x-3],d[x]);
	else if(maxx==k3)gz(d[x-3],d[x-2],d[x-1],d[x]);
}
void ycl(){													//预处理两点之间的直接距离
	FOR(i,sum)FOR(j,sum)
		IF(c[i],c[j]) g[i][j]=far(i,j)*p[c[i]];				//同一城市
		else g[i][j]=far(i,j)*t;							//不在同一城市
}
double floyd(){
	FOR(k,sum) FOR(i,sum) FOR(j,sum)						//floyd,时间复杂度o(n^3),空间复杂度o(n^2),均劣于dijskra
		g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
	double	mina=INF;
	For(i,(A-1)*4+1,A*4)  For(j,(B-1)*4+1,B*4)
		mina=min(mina,g[i][j]);								//起点有四个,终点有四个,枚举求最短的一条路
	return mina;
}
void gz(int*a,int*b1,int*b2,int*x){x[0]=b1[0]+b2[0]-a[0],x[1]=b1[1]+b2[1]-a[1];}//计算第四点(第四个机场)的坐标

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值