P1027 car的旅行路线

car的旅行路线

洛谷链接

这个题关键就是

如何把每个点表示出来,其实求出四个点的坐标后,只需要把这些点连接起来,用一遍folyed求出最短路径就好了。

代码:

 1 #include<cmath>
 2 #include<cstdio>
 3 int x[801],y[801];//x表示横坐标,y表示纵坐标 
 4 int ti[501];//在第i个城市中铁路单位里程价格 
 5 int n,s,tt,a,b;//tt表示航线单位里程价格 
 6 double d[501][501];//i到j的长度(花费) 
 7 void doit(int t1,int t2){//计算t1到t2的花费 
 8     d[t1][t2]=sqrt((x[t1]-x[t2])*(x[t1]-x[t2])
 9                 +(y[t1]-y[t2])*(y[t1]-y[t2]));//求t1到t2的长度 
10     if (((t1-1)/4)==((t2-1)/4)){//判断t1,t2是否在同一个城市内 
11         d[t1][t2]=d[t1][t2]*ti[(t1-1)/4+1];//计算花费 
12     }else
13         d[t1][t2]=d[t1][t2]*tt;
14     d[t2][t1]=d[t1][t2];//对称 
15     return;//结束 
16 }
17 int find(int t1,int t2,int t3){//找直角三角形斜边
18     //如果一边长度大于任意两边返回此边对着的点 
19     if((d[t1][t2]>d[t2][t3])&&(d[t1][t2]>d[t3][t1])) return t3;
20     //t1t2对应的点为t3 
21     if((d[t2][t3]>d[t1][t2])&&(d[t2][t3]>d[t3][t1])) return t1;
22     //t2t3对应的点为t1 
23     if((d[t3][t1]>d[t2][t3])&&(d[t3][t1]>d[t1][t2])) return t2;
24     //t1t3对应的点为t2 
25 }
26 void doit2(int t1,int t2,int t3){
27     doit(t1,t2);//t1到t2的花费(比在同一城市) 
28     doit(t2,t3);//t2到t3的花费(必在同一城市) 
29     doit(t3,t1);//t3到t1的花费(必在同一城市) 
30     int haha=find(t1,t2,t3);//找此直角三角形的斜边 
31     //而在平行四边形中
32     //一条边的两个顶点的横(或纵)坐标的差值
33     //等于其对边两个顶点的横(或纵)坐标的差值 
34     if(haha==t1){//看斜边对着的点为哪个,并求出第4个点的坐标 
35         x[t3+1]=x[t3]+x[t2]-x[t1]; 
36         y[t3+1]=y[t3]+y[t2]-y[t1];  
37     }
38     else if(haha==t2){
39         x[t3+1]=x[t3]+x[t1]-x[t2];  
40         y[t3+1]=y[t3]+y[t1]-y[t2];   
41     }
42     else if(haha==t3){
43         x[t3+1]=x[t1]+x[t2]-x[t3];  
44         y[t3+1]=y[t1]+y[t2]-y[t3];  
45     }
46 }
47 int main(){
48     scanf("%d",&n); 
49     for(;n>=1;n--){//循环运行n次 
50         scanf("%d %d %d %d",&s,&tt,&a,&b);
51         //S城市数,t飞机单价,A,B序号
52         int i,j,k;
53         for(i=1;i<=401;i++)//初始化 
54             for(j=1;j<=401;j++)
55                 d[i][j]=100000000;
56         for(i=1;i<=s;i++){
57             scanf("%d%d%d%d%d%d%d",
58             &x[4*i-3],&y[4*i-3],&x[4*i-2],
59             &y[4*i-2],&x[4*i-1],&y[4*i-1],
60             &ti[i]);
61             doit2(4*i-3,4*i-2,4*i-1);
62         }
63         for(i=1;i<=4*s;i++)
64             for(j=1;j<=4*s;j++)
65             doit(i,j);//计算i到j的花费 
66         for(k=1;k<=4*s;k++)
67             for(i=1;i<=4*s;i++)
68                 for(j=1;j<=4*s;j++)
69                     if(d[k][j]+d[i][k]<d[i][j])
70                         d[i][j]=d[k][j]+d[i][k];//Floyed
71         double ans=200000000.0;
72         for(i=4*a-3;i<=4*a;i++)
73             for(j=4*b-3;j<=4*b;j++)
74                 if(d[i][j]<ans)
75                     ans=d[i][j];//更新最小值 
76         printf("%.1lf\n",ans);//输出,并保留一位小数 
77     }
78     return 0;
79 }
View Code

 

posted @ 2017-05-08 15:58  江屿  阅读(270)  评论(0编辑  收藏  举报