题目链接:​​https://vijos.org/p/1119​

题目描述

又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。

那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。

Vijos - Car的旅行路线(最短路)_最短路

输入格式

第一行有四个正整数S,T,A,B。其中S(0<S<=100)表示城市的个数,T表示飞机单位里程的价格,A,B分别为城市A,B的序号,(1<=A,B<=S)。

接下来有S行,其中第I行均有7个正整数xi1,yi1,xi2,yi2,xi3,yi3,Ti,这当中的(xi1,yi1),(xi2,yi2),(xi3,yi3)分别是第I个城市中任意三个机场的坐标,T I为第I个城市高速铁路单位里程的价格。

输出格式

输出最小费用(结果保留两位小数)

样例输入


3 10 1 3
1 1 1 3 3 1 30
2 5 7 4 5 2 1
8 6 8 8 11 6 3


样例输出


47.55


解题思路

这个就是一道最短路问题,关键的就是已知矩形三个点的坐标,求出最后一个点的坐标,只要求出这个,剩下的就好做了,这是本人写的求法

求出四个点的坐标之后,题上说共有S个城市,那么我们可以得到4*S个点(每个城市4个点),然后分别求出一个点到其余各点的花费,城市四个点之间的按高铁的价格算,城市与城市按飞机的价格算,跑一遍最短路,最后求出A城市的四个点分别到B城市的四个点的最小花费,求出最小值即可。

#include <queue>
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
const double inf = 999999999;
typedef struct edge {
int x, y;
}coor;
coor e[450];
int vis[410];
double dis[410], map[410][410];
coor coordinate(coor a, coor b, coor c)
{
coor p;
p.x = b.x + c.x - a.x;
p.y = b.y + c.y - a.y;
return p;
}
bool Judge(coor a, coor b, coor c)
{
if (!((b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y)))
return true;
return false;
}
void Seeking(coor a[])
{
if (Judge(a[0], a[1], a[2]))
a[3] = coordinate(a[0], a[1], a[2]);
else if(Judge(a[1], a[0], a[2]))
a[3] = coordinate(a[1], a[0], a[2]);
else a[3] = coordinate(a[2], a[0], a[1]);
}
void Spfa(int s, int S)
{
queue <int> Q;
for (int i = 0; i < 4 * S; i++)
{
vis[i] = 0;
dis[i] = inf;
}
Q.push(s);
dis[s] = 0;
vis[s] = 1;
while (!Q.empty())
{
int u = Q.front();
Q.pop();
vis[u] = 0;
for (int j = 0; j < 4 * S; j++)
{
if (dis[j] > dis[u] + map[u][j])
{
dis[j] = dis[u] + map[u][j];
if (!vis[j])
{
vis[j] = 1;
Q.push(j);
}
}
}
}
}
int main()
{
coor a, b;
int S, T, A, B, TT[410];
while (~scanf("%d%d%d%d", &S, &T, &A, &B))
{
double minn = inf;
for (int i = 0; i < 4 * S; i++)
for (int j = 0; j < 4 * S; j++)
map[i][j] = inf;
for (int i = 0; i < 4 * S; i += 4)
{
for (int j = 0; j < 3; j++)
scanf("%d%d", &e[i + j].x, &e[i + j].y);
scanf("%d", &TT[i]);
Seeking(e + i);
}
for (int i = 0; i < 4 * S; i += 4)
{
for (int j = 0; j < 4; j++)
{
a = e[i + j];
for (int k = i + j + 1; k < i + 4; k++)
{
b = e[k];
map[k][i + j] = map[i + j][k] = TT[i] * sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
for (int k = i + 4; k < 4 * S; k++)
{
b = e[k];
map[k][i + j] = map[i + j][k] = T * sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
}
}
for (int i = 0; i < 4; i++)
{
int u = (A - 1) * 4 + i;
Spfa(u, S);
for (int j = 0; j < 4; j++)
{
int v = (B - 1) * 4 + j;
if (minn > dis[v])
minn = dis[v];
}
}
printf("%.2lf\n", minn);
}
return 0;
}