[Solución de preguntas] Luogu P1027 Ruta de viaje en automóvil

Ir a: Mi propio blog

tema

Itinerario del auto P1027 en Los Valley

responder

Esta pregunta requiere el camino más corto. El aeropuerto en la pregunta representa un punto, pero no se dan las coordenadas de algunos puntos, lo que requiere el uso de conocimientos geométricos. Hay ciertas habilidades en la forma de ahorrar puntos para esta pregunta. El subíndice del aeropuerto de la ciudad con el número de serie i es 4 * i, 4 * i + 1, 4 * i + 2, 4 * i + 3, de modo que la ciudad y el aeropuerto se pueden numerar Conectar.

Código

#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;
}

Supongo que te gusta

Origin blog.csdn.net/zjgmartin/article/details/108415484
Recomendado
Clasificación