洛谷 P1027 [NOIP2001 提高组] Car 的旅行路线 【最短路】

题目链接

题意:

s s s 个城市,每个城市有4个机场呈矩形分布,城市内的机场两两之间高速连接,城市间机场有飞机航线连接,求城市 S 到城市 T 的最少花费

题解:

计算出每个城市第四个机场位置,建图跑一遍Floyd

#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;

#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))

const int mod = 1e9+7;
int qpow(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e7+10;

int n,m,s,t;
double dis[405][405];
struct pos{
	int x[5],y[5],c;//城市4个机场的坐标及高速单位里程价格
	void get4(){//计算第四个点坐标
		int x12=x[1]-x[2],y12=y[1]-y[2],x23=x[2]-x[3],y23=y[2]-y[3],x13=x[1]-x[3],y13=y[1]-y[3];
		if(x12*x23+y12*y23==0) x[4]=x[3]+x12,y[4]=y[3]+y12;
		else if(x12*x13+y12*y13==0) x[4]=x[2]-x13,y[4]=y[2]-y13;
		else x[4]=x[1]+x23,y[4]=y[1]+y23;
	}
}p[105];
double getdis(int i,int j,int u,int v){
//计算城市i的u机场到城市j的v机场的距离
	return sqrt((p[i].x[u]-p[j].x[v])*(p[i].x[u]-p[j].x[v])+(p[i].y[u]-p[j].y[v])*(p[i].y[u]-p[j].y[v]));
}

#define endl '\n'
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int _; cin>>_;
	while(_--){
		cin>>n>>m>>s>>t;
		for(int i=1;i<=4*n;i++)for(int j=1;j<=4*n;j++)dis[i][j]=i==j?0:INF;
		for(int i=1;i<=n;i++){
			cin>>p[i].x[1]>>p[i].y[1]>>p[i].x[2]>>p[i].y[2]>>p[i].x[3]>>p[i].y[3]>>p[i].c;
			p[i].get4();
			for(int u=1;u<=4;u++)for(int v=1;v<=4;v++){
				if(u==v)continue;
				dis[u+4*(i-1)][v+4*(i-1)]=p[i].c*getdis(i,i,u,v);
				//高速
			}		
		}
		for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){
			if(i==j)continue;
			for(int u=1;u<=4;u++)for(int v=1;v<=4;v++)
				dis[u+4*(i-1)][v+4*(j-1)]=m*getdis(i,j,u,v);
				//飞机
		}
		for(int k=1;k<=4*n;k++)
			for(int i=1;i<=4*n;i++)
				for(int j=1;j<=4*n;j++)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
		double ans=INF;
		for(int i=(s-1)*4+1;i<=s*4;i++)
			for(int j=(t-1)*4+1;j<=t*4;j++)
				ans=min(ans,dis[i][j]);
		cout<<fixed<<setprecision(1)<<ans<<endl;
	}	
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值