【P1027 [NOIP2001 提高组] Car 的旅行路线】
思路:
单源最短路问题,首先输入数据只给了每个城市的三个点的坐标,第四个点的坐标必须自己思考,但是这四个点的相对几何位置不固定,因此需要用迭代法不断交换三个点的位置:A-B-C --> B-C-A --> C-A-B......直到三个点的位置如图所示,这样就可以求出第四个点的坐标了,然后再用数组构造一个图,同一城市机场间的边的长度=机场间的距离该城市铁路单价,不同城市的机场间的边长=机场间的距离飞机票单价,再用最短路算法求解,最佳算法是dijkstra。

#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
#include <algorithm>
#define INF 10000000
#define CTOA(x) (((x-1)<<2)+1) 
#define DISTANCE(x1,y1,x2,y2) ((double)sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))) 
using namespace std;
double node[4050][4050]; 
double T; 
int tx[3],ty[3],t;
double ans=INF;
struct city
{
	int x[4];
	int y[4];
}ct[105]; 
void getfour(int c) 
{
	int tt;
	memcpy(tx,ct[c].x,sizeof(tx));
	memcpy(ty,ct[c].y,sizeof(ty));
	while((tx[0]-tx[1])*(tx[2]-tx[1])+(ty[0]-ty[1])*(ty[2]-ty[1])) 
	{
		tt=tx[0]; tx[0]=tx[1]; tx[1]=tx[2]; tx[2]=tt;
		tt=ty[0]; ty[0]=ty[1]; ty[1]=ty[2]; ty[2]=tt; 
	}
	ct[c].x[3]=tx[0]-tx[1]+tx[2];
	ct[c].y[3]=ty[0]-ty[1]+ty[2];
}
int min(int a1,int b1)
{
	if(a1<b1) return a1;
	return b1;
}
int main()
{
	int i,j,k,l,m,n;
	scanf("%d",&n);
	while(n--)
	{
		int s,t,a,b;
		cin>>s>>t>>a>>b;
		if(a==b) { cout<<"0.0\n"; continue;} 
		int airport=s<<2; 
		for(i=1;i<=airport;i++)
		{
			for(j=1;j<=airport;j++)
				node[i][j]=INF; 
		}
		for(i=1;i<=s;i++)
		{
			for(j=0;j<3;j++)
				cin>>ct[i].x[j]>>ct[i].y[j];
			cin>>T;
			getfour(i); 
			for(j=0;j<4;j++)
			{
				for(k=0;k<4;k++)
					if(j!=k) 
						node[CTOA(i)+j][CTOA(i)+k]=(DISTANCE(ct[i].x[j],ct[i].y[j],ct[i].x[k],ct[i].y[k])*T);
			}
		}
		for(i=1;i<=s;i++)
		{
			for(j=1;j<=s;j++)
			{
				if(i!=j) 
					for(k=0;k<4;k++)
					{
						for(l=0;l<4;l++) 
							node[CTOA(i)+k][CTOA(j)+l]=(DISTANCE(ct[i].x[k],ct[i].y[k],ct[j].x[l],ct[j].y[l])*t);
					}
			}
		}
		//Floyd
		for(k=1;k<=airport;k++)
		{
			for(i=1;i<=airport;i++)
			{
				for(j=1;j<=airport;j++)
				{
					node[i][j]=min(node[i][j],node[i][k]+node[k][j]);
				}
			}
		}
		for(i=0;i<4;i++)
		{
			for(j=0;j<4;j++)
				ans=min(ans,node[CTOA(a)+i][CTOA(b)+j]);
		}
		cout<<setiosflags(ios::fixed)<<setprecision(1)<<ans<<endl;
	}
	return 0;
}