【NOIP 2001提高组】Car的旅行路线(car.cpp)

来源:互联网 发布:淘宝网宝贝分类怎么弄 编辑:程序博客网 时间:2024/04/30 21:31
Car的旅行线路(car.cpp)


题目描述
又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。 她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。 那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。 任务: 找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。


输入
第一行为一个正整数n(1≤n≤10),表示有n组测试数据。


每组的第一行有四个正整数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个城市中任意三个机场的坐标,TI为第I个城市高速铁路单位里程的价格。


输出
共有n行,每行一个数据对应测试数据,结果保留2位小数。


样例输入
1
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

    这道题题目描述极其恶心(所以理所当然与拯救公主一起进入了我的恶心题百科全书),那么我们一口一口地慢慢吃掉这个大胖子~

    1.我们很容易想到,第一步是算第四个点~那么如何计算呢?一开始我把此题想得很简单:矩形的话,知道三个坐标,就找相同的横坐标和纵坐标,然后把不与任何一个点相同的横坐标与纵坐标相组合,即可得到第四个点(我的描述有些难理解,可以看看图)

                

    但是,现实无情的打击了我……矩形还可以是这样的:

                 

    55555……只能重新思考了……其实呢,我们可以发现,三个点一定有一个是直角顶点,而另外两个顶点相加减去直角顶点,坐标刚好等于第四个点(可以去试试,没有错)!可是问题来了!怎么找直角顶点呢?其实,三个点能连成三条线,那么最长的一条线对面的那个点,就是直角顶点~

                 

    2.解决坐标后,什么都简单了~记录两点间费用,然后Floyed~

    3.没有3了~直接看代码吧~

#include<cstdio>#include<cmath>#include<algorithm>#include<cstring>using namespace std;struct node{int x,y;}City[105][5];int mon[105];double Mon[105][5][105][5];double way(node a,node b){return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0));}void four(int o){double p[4];int maxx;int maxn=0;for(int i=1;i<=2;i++){for(int j=i+1;j<=3;j++){p[6-i-j]=way(City[o][i],City[o][j]);if(p[6-i-j]>maxn){maxn=p[6-i-j];maxx=6-i-j;}}}swap(City[o][maxx],City[o][1]);City[o][4].x=City[o][2].x+City[o][3].x-City[o][1].x;City[o][4].y=City[o][2].y+City[o][3].y-City[o][1].y;}int A,B,S,T,t;double minn=1000000;int main(){//freopen("car.in","r",stdin);//freopen("car.out","w",stdout);scanf("%d",&t);for(;t;t--){scanf("%d %d %d %d",&S,&T,&A,&B);for(int i=1;i<=S;i++){for(int j=1;j<=3;j++){scanf("%d %d",&City[i][j].x,&City[i][j].y);}scanf("%d",&mon[i]);four(i);}if(A==B){printf("0.00\n");continue;}for(int i=1;i<=S;i++){for(int j=1;j<=4;j++){for(int k=1;k<=S;k++){for(int l=1;l<=4;l++){if(i==k){Mon[i][j][k][l]=way(City[i][j],City[k][l])*mon[i];}else{Mon[i][j][k][l]=way(City[i][j],City[k][l])*T;}}}}}for(int i=1;i<=S;i++){for(int in=1;in<=4;in++){for(int j=1;j<=S;j++){for(int jn=1;jn<=4;jn++){for(int k=1;k<=S;k++){for(int kn=1;kn<=4;kn++){if(Mon[j][jn][i][in]+Mon[i][in][k][kn]<Mon[j][jn][k][kn]){Mon[j][jn][k][kn]=Mon[j][jn][i][in]+Mon[i][in][k][kn];}}}}}}}for(int i=1;i<=4;i++){for(int j=1;j<=4;j++){if(Mon[A][i][B][j]<minn){minn=Mon[A][i][B][j];}}}printf("%.2lf\n",minn);minn=1000000;}}


2 0
原创粉丝点击