蓝桥杯 算法训练 Car的旅行路线(Floyd算法)
那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
S表示城市的个数,t表示飞机单位里程的价格,A,B分别为城市A,B的序号,(1<=A,B<=S)。
接下来有S行,每行均有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
其实这道题不是很难,把各个机场编号,就能建立无向图G【i】【j】表示各个机场之间通行的花费,然后用Floyd算法求出最短路即可。有一个难点在于利用矩形条件求各个城市最后一个机场坐标,我们利用矩形两组不相邻的顶点坐标之和相等来求。具体解析见代码:
#include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
#include<cstring>
#include<cmath>
#define Inf 99999999
using namespace std;
struct City
{
float x[4];
float y[4];
float cost;
}city[100];
void Seek(struct City c,float &x3,float &y3)
{
if((c.x[0]-c.x[1])*(c.x[2]-c.x[1])+(c.y[0]-c.y[1])*(c.y[2]-c.y[1])==0) //直角点是(x[1],y[1])
{swap(c.x[0],c.x[1]);swap(c.y[0],c.y[1]);}
else if((c.x[0]-c.x[2])*(c.x[1]-c.x[2])+(c.y[0]-c.y[2])*(c.y[1]-c.y[2])==0)//直角点是(x[2],y[2])
{swap(c.x[0],c.x[2]);swap(c.y[0],c.y[2]);}
x3=c.x[1]+c.x[2]-c.x[0];
y3=c.y[1]+c.y[2]-c.y[0];
}
float dis(struct City a,int index1,struct City b,int index2)
{
return sqrt((a.x[index1]-b.x[index2])*(a.x[index1]-b.x[index2])+(a.y[index1]-b.y[index2])*(a.y[index1]-b.y[index2]));
}
int main()
{
float G[405][405];
int s,t,a,b;
cin>>s>>t>>a>>b;
for(int i=0; i<s; i++)
{
for(int u=0;u<3;u++)
{
cin>>city[i].x[u]>>city[i].y[u];
}
cin>>city[i].cost;
float x3,y3;
Seek(city[i],x3,y3);
city[i].x[3]=x3;
city[i].y[3]=y3;
}
for(int i=0; i<4*s; i++)
for(int j=0; j<4*s; j++)
{
if(i==j)
G[i][j]=0;
else if(i/4==j/4)
G[i][j]=dis(city[i/4],i%4,city[j/4],j%4)*city[i/4].cost;
else
G[i][j]=dis(city[i/4],i%4,city[j/4],j%4)*t;
}
for(int k=0; k<4*s; k++)
for(int i=0; i<4*s; i++)
for(int j=0; j<4*s; j++)
{
G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
}
float mindis=Inf;
for(int i=4*a-4; i<4*a; i++)
for(int j=4*b-4; j<4*b; j++)
{
mindis=min(mindis,G[i][j]);
}
printf("%.1f\n",mindis);
return 0;
}
其实这道题博主写了两个小时,本来三十分钟就能ac的题emmm,原因是之前好像是听哪个老师还是算法书上说,floyd算法k放在最外层或者最内层都行。。。。然后今天一查才知道,k只能放在最外层!!!看了知乎上大手子的讲解,算是明白为什么了。在动态规划算法进行到k时,必须保证k-1时的状态完全得到更新。
附上知乎大手子的讲解: