【题解】洛谷P1027 Car的旅行路线

前往:我自己搭建的博客

题目

洛谷P1027 Car的旅行路线

题解

此题要求最短路。题中的机场代表点,但有部分点的坐标没有给出,需要运用几何知识求出。此题的存点方式有一定技巧,序号为i的城市的机场下标为4*i,4*i+1,4*i+2,4*i+3,这样可以将城市与机场的编号关联起来。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=500;
const double inf=2000000000;
int n,a,b;
double plane;
bool vis[maxn];
double d[maxn],p[maxn];	//p[i]表示序号为i的城市的铁路单价 
struct airport{double x,y;}v[maxn];
inline void get_place()	//求出第四个机场的坐标 
{
	double l1,l2,l3;	
	for(int i=1;i<=n;i++)
	{
		l1=sqrt((v[i<<2].x-v[i<<2|1].x)*(v[i<<2].x-v[i<<2|1].x)+(v[i<<2].y-v[i<<2|1].y)*(v[i<<2].y-v[i<<2|1].y));
		l2=sqrt((v[i<<2].x-v[i<<2|2].x)*(v[i<<2].x-v[i<<2|2].x)+(v[i<<2].y-v[i<<2|2].y)*(v[i<<2].y-v[i<<2|2].y));
		l3=sqrt((v[i<<2|1].x-v[i<<2|2].x)*(v[i<<2|1].x-v[i<<2|2].x)+(v[i<<2|1].y-v[i<<2|2].y)*(v[i<<2|1].y-v[i<<2|2].y));
		double mx=-1; int mv;	//找出四个机场的一条对角线 
		if(l1>mx) mx=l1,mv=1;
		if(l2>mx) mx=l2,mv=2;
		if(l3>mx) mx=l3,mv=3;
		if(mv==1) v[i<<2|3].x=v[i<<2].x+v[i<<2|1].x-v[i<<2|2].x,v[i<<2|3].y=v[i<<2].y+v[i<<2|1].y-v[i<<2|2].y;
		else if(mv==2) v[i<<2|3].x=v[i<<2].x+v[i<<2|2].x-v[i<<2|1].x,v[i<<2|3].y=v[i<<2].y+v[i<<2|2].y-v[i<<2|1].y;
		else v[i<<2|3].x=v[i<<2|1].x+v[i<<2|2].x-v[i<<2].x,v[i<<2|3].y=v[i<<2|1].y+v[i<<2|2].y-v[i<<2].y;
	}
}
inline double get_price(int a,int b)	//求从机场a->b的直达价格 
{
	double dist=sqrt((v[a].x-v[b].x)*(v[a].x-v[b].x)+(v[a].y-v[b].y)*(v[a].y-v[b].y));
	if(a>>2==b>>2) return dist*p[a>>2];
	else return dist*plane;
}
priority_queue<pair<int,int> > q;
inline void dijkstra(int s)
{
	memset(vis,0,sizeof(vis));
	for(int i=4;i<=(n<<2|3);i++) d[i]=inf;
	d[s]=0; q.push(make_pair(0,s));
	while(q.size())
	{
		int x=q.top().second; q.pop();
		if(vis[x]) continue; vis[x]=1;
		for(int y=4;y<=(n<<2|3);y++)
		{
			if(x==y) continue;
			double w=get_price(x,y);
			if(d[y]>d[x]+w) 
			{
				d[y]=d[x]+w;
				q.push(make_pair(-d[y],y));
			}
		}
	}
}

int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		scanf("%d%lf%d%d",&n,&plane,&a,&b);
		for(int i=1;i<=n;i++) scanf("%lf%lf%lf%lf%lf%lf%lf",&v[i<<2].x,&v[i<<2].y,&v[i<<2|1].x,&v[i<<2|1].y,&v[i<<2|2].x,&v[i<<2|2].y,&p[i]);
		get_place(); double ans=inf;
		for(int i=a<<2;i<=(a<<2|3);i++)	//分别尝试城市a的四个机场 
		{
			dijkstra(i);
			for(int j=b<<2;j<=(b<<2|3);j++)	//分别尝试城市b的四个机场
			{
				ans=min(ans,d[j]);
			}
		}
		printf("%.1f\n",ans);
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zjgmartin/article/details/108415484
今日推荐