您的位置:首页 > 其它

VIJOS P1119 (NOIP2001 Problem4):Car的旅行路线 Accepted

2006-11-11 20:16 429 查看
描述 Description
  又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。
  那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
输入格式 Input Format
  第一行有四个正整数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个城市高速铁路单位里程的价格。
输出格式 Output Format
输出最小费用(结果保留两位小数)
最短路问题,用Dijkstra算法可以完美解决。

难点在于建图。

假设未知坐标为p4(x4,y4),已知坐标分别是p1(x1,y1) p2(x2,y2) p3(x3,y3)

先根据垂直向量积为零判断每个矩形缺失的坐标位置,如果p1是p4的对角,则

(x3-x1)(x2-x1)+(y3-y1)(y2-y1)=0

由中点公式易知

x4=x3+x2-x1

y4=y3+y2-y1

下面可以开始构图了。

我构图的方案是以城市为单位,先计算内部火车线路之间的边权(火车价格*距离),然后计算该城市各机场与其他城市每一个机场之间的边权(飞机单价*距离)。这样完成以后就得到一张稠密的无向图。剩下的工作就是最短路径的标程了。

还值得注意的一点是,Dijkstra开始的时候应该把起始城市的4个机场最短距离都设为0。


#include<stdio.h>


#include<math.h>


#include<stdbool.h>


#define BIG 999999.0




void Dijkstra(void);


float dist(float x1,float y1,float x2,float y2);


void construct(void);




typedef struct




...{


float x,y;


}Point;


Point ct[100][4];


int rail[100];


int s,t,a,b;


float dis[100];


float g[400][400];




int main(void)




...{


int i,j,k;


float answer=BIG;


FILE *fin=stdin;


fscanf(fin,"%d %d %d %d ",&s,&t,&a,&b);


for(i=0;i<s;i++)


fscanf (


fin,"%f %f %f %f %f %f %d ",


&ct[i][0].x,&ct[i][0].y,


&ct[i][1].x,&ct[i][1].y,


&ct[i][2].x,&ct[i][2].y,


&rail[i]


);


construct();//构图


Dijkstra();




for (i=0;i<4;i++)...{


if(dis[(b-1)*4+i]<answer)


answer=dis[(b-1)*4+i];


}


printf("%.2f ",answer);


return 0;


}


void construct(void)




...{


int i,j,k,l;




for (i=0;i<s;i++)...{ //计算第四个点的坐标


if((ct[i][1].x-ct[i][0].x)*(ct[i][2].x-ct[i][0].x)




+(ct[i][1].y-ct[i][0].y)*(ct[i][2].y-ct[i][0].y)==0)...{


ct[i][3].x=ct[i][2].x+ct[i][1].x-ct[i][0].x;


ct[i][3].y=ct[i][2].y+ct[i][1].y-ct[i][0].y;


}else if((ct[i][0].x-ct[i][1].x)*(ct[i][2].x-ct[i][1].x)




+(ct[i][0].y-ct[i][1].y)*(ct[i][2].y-ct[i][1].y)==0)...{


ct[i][3].x=ct[i][2].x+ct[i][0].x-ct[i][1].x;


ct[i][3].y=ct[i][2].y+ct[i][0].y-ct[i][1].y;


}else if((ct[i][0].x-ct[i][2].x)*(ct[i][1].x-ct[i][2].x)




+(ct[i][0].y-ct[i][2].y)*(ct[i][1].y-ct[i][2].y)==0)...{


ct[i][3].x=ct[i][1].x+ct[i][0].x-ct[i][2].x;


ct[i][3].y=ct[i][1].y+ct[i][0].y-ct[i][2].y;


}


}




for(i=0;i<s;i++)...{//以城市为单位构图


for(j=0;j<4;j++)//城市内部


for(k=0;k<4;k++)


g[4*i+j][4*i+k]=


rail[i]*dist(ct[i][j].x,ct[i][j].y,ct[i][k].x,ct[i][k].y);




for(j=0;j<s;j++)...{//城市之间


if(j==i)continue;


for(k=0;k<4;k++)


for(l=0;l<4;l++)


g[4*i+k][4*j+l]=


t*dist(ct[i][k].x,ct[i][k].y,ct[j][l].x,ct[j][l].y);


}


}


}


float dist(float x1,float y1,float x2,float y2)




...{


return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));


}


void Dijkstra(void)




...{


int i,j;


int min=BIG,minn;


bool vis[100];


memset(vis,0,sizeof(vis));


for(i=0;i<s*4;i++)


dis[i]=BIG;


dis[a-1]=dis[a]=dis[a+1]=dis[a+2]=0;




for(i=0;i<s*4;i++)...{


min=BIG;




for(j=0;j<s*4;j++)...{




if(!vis[j] && dis[j]<min)...{


min=dis[j];


minn=j;


}


}


vis[minn]=true;




for(j=0;j<4*s;j++)...{


if(min+g[minn][j]<dis[j])


dis[j]=dis[minn]+g[minn][j];


}


}


}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: