描述
又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。
那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
格式
输入格式
第一行有四个正整数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个城市高速铁路单位里程的价格。
输出格式
输出最小费用(结果保留两位小数)
限制
每个测试点1s
来源
NOIP2001第四题
题不难,但相当考验编程能力,,这题在考场上要有耐心
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<vector> 8 #include<queue> 9 #include<fstream> 10 using namespace std; 11 const int inf=1e9; 12 int N,city_num,S,T; 13 int fly_cost; 14 int tot; 15 struct node{ 16 int x[5],y[5]; 17 }Airport[200]; 18 int road_cost[200]; 19 int vis[200][200]; 20 int to[200][200]; 21 double cost[200][200]; 22 double ANS; 23 int min1(double a1,double a2){ 24 if(a1<a2) return a1; 25 else return a2; 26 } 27 void calc_roadcost(int xx){//计算机场之间的铁路费用,xx表示机场标号 28 29 for(int i=1;i<=4;i++){//机场标号 30 int u=4*(xx-1)+i;//在图中代表的点的标号 31 for(int j=1;j<=4;j++){//机场标号 32 int v=4*(xx-1)+j;//在图中代表的点的标号 33 if(u!=v&&vis[u][v]==0&&vis[v][u]==0){//如果不是同一个点,且没有建立过连接 34 vis[u][v]=1; vis[v][u]=1; 35 int e=++to[u][0]; 36 int r=++to[v][0]; 37 to[u][e]=v; to[v][r]=u; 38 39 double dis=((double)Airport[xx].x[i]-(double)Airport[xx].x[j])*((double)Airport[xx].x[i]-(double)Airport[xx].x[j])+ 40 ((double)Airport[xx].y[i]-(double)Airport[xx].y[j])*((double)Airport[xx].y[i]-(double)Airport[xx].y[j]); 41 dis=sqrt(dis); 42 dis*=(double)road_cost[xx]; 43 cost[u][e]=dis; cost[v][r]=dis; 44 } 45 } 46 } 47 48 } 49 50 void calc_fly_cost(){//计算机场之间的航线费用 51 52 for(int i=1;i<=city_num;i++){//城市标号 53 for(int j=1;j<=4;j++){//城市中的机场 54 int u=4*(i-1)+j;//此机场在图中的标号 55 for(int k=1;k<=city_num;k++){//城市标号 56 if(k!=i){//保证不是同一个城市 57 for(int t=1;t<=4;t++){//城市中的机场 58 int v=4*(k-1)+t;//此机场在图中的标号 59 60 if(vis[u][v]==0&&vis[v][u]==0){//没有建立过连接 61 vis[u][v]=1; vis[v][u]=1; 62 int e=++to[u][0]; 63 int r=++to[v][0]; 64 65 to[u][e]=v; to[v][r]=u; 66 double dis=sqrt(((double)Airport[i].x[j]-(double)Airport[k].x[t])*((double)Airport[i].x[j]- 67 (double)Airport[k].x[t])+((double)Airport[i].y[j]-(double)Airport[k].y[t])* 68 ((double)Airport[i].y[j]-(double)Airport[k].y[t])); 69 dis*=(double)fly_cost; 70 cost[u][e]=dis; cost[v][r]=dis; 71 72 } 73 else continue; 74 } 75 } 76 else continue; 77 } 78 } 79 } 80 81 } 82 void SPFA(int s){ 83 84 static queue<int> Q; 85 double dis[200]; 86 bool vis2[200]; 87 88 for(int i=0;i<=199;i++) dis[i]=(double)inf; 89 memset(vis2,false,sizeof(vis2)); 90 while(Q.size()>0) Q.pop(); 91 92 dis[s]=(double)0; 93 Q.push(s); vis2[s]=true; 94 95 while(Q.size()>0){ 96 int x=Q.front(); Q.pop(); 97 vis2[x]=false; 98 for(int i=1;i<=to[x][0];i++){ 99 int y=to[x][i]; 100 if(dis[y]>dis[x]+cost[x][i]){ 101 dis[y]=dis[x]+cost[x][i]; 102 if(vis2[y]==false){ 103 vis2[y]=true; 104 Q.push(y); 105 } 106 } 107 } 108 } 109 110 for(int i=1;i<=4;i++){ 111 int v=4*(T-1)+i; 112 if(dis[v]<(double)ANS){ 113 ANS=dis[v]; 114 } 115 } 116 117 } 118 inline double calc_dis(int x1,int x2,int y1,int y2){//两点间距离的平方 119 return ((double)x1-(double)x2)*((double)x1-(double)x2)+ 120 ((double)y1-(double)y2)*((double)y1-(double)y2); 121 } 122 int main(){ 123 scanf("%d%d%d%d",&city_num,&fly_cost,&S,&T); 124 tot=4*city_num; 125 for(int j=1;j<=city_num;j++){ 126 scanf("%d%d%d%d%d%d%d",&Airport[j].x[1],&Airport[j].y[1], 127 &Airport[j].x[2],&Airport[j].y[2], 128 &Airport[j].x[3],&Airport[j].y[3], 129 &road_cost[j]); 130 131 if(calc_dis(Airport[j].x[1],Airport[j].x[2],Airport[j].y[1],Airport[j].y[2])== 132 calc_dis(Airport[j].x[1],Airport[j].x[3],Airport[j].y[1],Airport[j].y[3])+ 133 calc_dis(Airport[j].x[2],Airport[j].x[3],Airport[j].y[2],Airport[j].y[3]) 134 )//说明 3是直角顶点 135 Airport[j].x[4]=Airport[j].x[1]+Airport[j].x[2]-Airport[j].x[3], 136 Airport[j].y[4]=Airport[j].y[1]+Airport[j].y[2]-Airport[j].y[3]; 137 138 else if(calc_dis(Airport[j].x[1],Airport[j].x[3],Airport[j].y[1],Airport[j].y[3])== 139 calc_dis(Airport[j].x[1],Airport[j].x[2],Airport[j].y[1],Airport[j].y[2])+ 140 calc_dis(Airport[j].x[3],Airport[j].x[2],Airport[j].y[3],Airport[j].y[2]) 141 )//说明 2是直角顶点 142 Airport[j].x[4]=Airport[j].x[1]+Airport[j].x[3]-Airport[j].x[2], 143 Airport[j].y[4]=Airport[j].y[1]+Airport[j].y[3]-Airport[j].y[2]; 144 145 else if(calc_dis(Airport[j].x[2],Airport[j].x[3],Airport[j].y[2],Airport[j].y[3])== 146 calc_dis(Airport[j].x[2],Airport[j].x[1],Airport[j].y[2],Airport[j].y[1])+ 147 calc_dis(Airport[j].x[3],Airport[j].x[1],Airport[j].y[3],Airport[j].y[1]) 148 )//说明 1是直角顶点 149 Airport[j].x[4]=Airport[j].x[2]+Airport[j].x[3]-Airport[j].x[1], 150 Airport[j].y[4]=Airport[j].y[2]+Airport[j].y[3]-Airport[j].y[1]; 151 152 calc_roadcost(j);//计算机场之间的铁路费用 153 } 154 calc_fly_cost();//计算机场之间的航线费用 155 ANS=inf; 156 for(int i=1;i<=4;i++){ 157 int from=4*(S-1)+i; 158 SPFA(from); 159 } 160 printf("%.2f",ANS); 161 return 0; 162 }