又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。
那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
任务
找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
第一行为一个正整数n(0<=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个城市中任意三个机场的坐标,T I为第I个城市高速铁路单位里程的价格。
共有n行,每行一个数据对应测试数据。
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.5
如描述
思路分析:求出第四个点,一开始感觉什么高大上呢,其实就是勾股定理,三种情况,稍微注意下存边,再加上最短路就好,做了半天,当在同一城市时火车的价钱打成了机场的,卡了好久MD,加强静态查错能力。。
PS:基本上是看了(http://wenku.baidu.com/link?url=n3hmdiEGTq9j-cBOP7ZUC7t6Ea8FwG6vbrFDTeKhe5hi_x3flKpzelERXByhlQ2gbj7kzJXyZBwSkgAPIxISrkDzIp5bEl0oI9aP5tWbc-a),讲得很好。
Source:
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 int n,vf,start,end,s; 8 int map[410][3],vn[410]; 9 bool used[410]; 10 double ans[410]; 11 double dist(int x1,int y1,int x2,int y2) 12 { 13 return (sqrt(pow((x1-x2),2)+pow((y1-y2),2))); 14 } 15 void dijistra()//dijistra求最短路 。 16 { 17 int i,j,now,apt; 18 double minn,u; 19 memset(used,0,sizeof(used)); 20 memset(ans,0,sizeof(ans)); 21 minn=99999999; 22 used[start*4]=true; 23 used[start*4-1]=true; 24 used[start*4-2]=true; 25 used[start*4-3]=true; 26 while (1==1) 27 { 28 minn=9999999; 29 for (i=1;i<=4*n;i++)//枚举被经过的机场,对其余未被经过的机场进行dijstra。 30 { 31 if (used[i]) 32 { 33 now=(i-1)/4+1; 34 for (j=1;j<=4*now-4;j++)// 若未被经过的机场dis值最小的在当前最短路的机场所在城市"前面",枚举所在城市的前面的机场。 35 { 36 if (!used[j]) 37 { 38 u=ans[i]+dist(map[i][1],map[i][2],map[j][1],map[j][2])*vf; 39 if (u<minn) 40 { 41 minn=u; 42 apt=j;//记录机场位置 43 } 44 } 45 } 46 47 for (j=4*now-3;j<=4*now;j++)//若未被经过的机场dis值最小的和当前最短路的机场处于同一个城市,换交通方式。 48 { 49 if (!used[j]) 50 { 51 u=ans[i]+dist(map[i][1],map[i][2],map[j][1],map[j][2])*vn[now]; 52 if (u<minn) 53 { 54 minn=u; 55 apt=j; 56 } 57 } 58 } 59 for (j=4*now+1;j<=4*n;j++)//同第一种情况。 60 { 61 if (!used[j]) 62 { 63 u=ans[i]+dist(map[i][1],map[i][2],map[j][1],map[j][2])*vf; 64 if (u<minn) 65 { 66 minn=u; 67 apt=j; 68 } 69 } 70 } 71 72 } 73 } 74 if ((apt==4*end-3) || (apt==4*end-2) || (apt==4*end-1) || (apt==4*end)) 75 { 76 printf("%.1lf ",minn); 77 return; 78 } 79 else 80 { 81 used[apt]=true; 82 83 ans[apt]=minn; 84 } 85 // } 86 } 87 } 88 void rf()//读入+根据平面内三点,求出第四个点的坐标。 89 { 90 int i; 91 int x,x1,x2,x3,y1,y2,y3,y; 92 scanf("%d%d%d%d",&n,&vf,&start,&end); 93 if (start==end) 94 { 95 printf("%.1lf",0.0); 96 return; 97 } 98 else 99 for (i=1;i<=n;i++) 100 { 101 scanf("%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&vn[i]); 102 x=x1+x2-x3; y=y1+y2-y3; 103 if (dist(x1,y1,x2,y2)!=dist(x3,y3,x,y)) 104 { 105 x=x1+x3-x2; 106 y=y1+y3-y2; 107 if (dist(x1,y1,x3,y3)!=dist(x2,y2,x,y)) 108 { 109 x=x2+x3-x1; 110 y=y2+y3-y1; 111 } 112 } 113 map[i*4-3][1]=x1; map[i*4-3][2]=y1; 114 map[i*4-2][1]=x2; map[i*4-2][2]=y2; 115 map[i*4-1][1]=x3; map[i*4-1][2]=y3; 116 map[i*4][1]=x; map[i*4][2]=y; 117 } 118 dijistra(); 119 } 120 121 int main() 122 { 123 int i; 124 scanf("%d",&s); 125 for (i=1;i<=s;i++) 126 { 127 memset(map,0,sizeof(map)); 128 //memset(ans,0,sizeof(ans)); 129 rf(); 130 } 131 return 0; 132 }