【计算几何】Car的旅行路线【NOIP2…
2015-02-02 19:25
288 查看
Car的旅行路线【NOIP2001提高组】
Time Limit:10000MS Memory
Limit:65536KTotal Submit:18 Accepted:7
Description
又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。图例 那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。任务: 找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。 输入:文件输入。 输出:输出最小费用,小数点后保留1位。输入格式: 第一行为一个正整数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行,每行一个数据对应测试数据。样例:输入11 10 1 31 1 1 3 3 1 302 5 7 4 5 2 18 6 8 8 11 6 3输出:47.55
Input
Output
Sample
Input
Sample
Output
Source
(1) 首先判断直角的位置:
因为从测试数据文件中读入的三个点的坐标是无序的,因此需判断直角的位置,然后在计算第四个点的坐标。如图,对于线段L1、L2,如果(x1-x2)*(x3-x2)+(y1-y2)*(y3-y2)=0,那么L1
⊥ L2。 (2) 计算(x4,y4): 如图:由x4-x3=x1-x2得x4=x1-x2+x3,同样的y4=y1-y2+y3 (3) 用邻接表或邻接矩阵把各个(机场)点之间的连接关系表示出来。 (4) 计算各条高速铁路的长度l,并求出每个城市中每条高速铁路的总价:Ti * l (5) 计算各条飞机航线的长度l',并求出每条航线的总价:t * l' 用Dijkstra计算各点间的最短路径,求出费用最少的路线。 DIJKSTRA算法算法思想: 设置一个顶点集合S并不断地作贪心选择来扩大这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。DIJKSTRA算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist做必要的修改。一旦S包含了所有V中的顶点,dist就记录了从源到所有其他顶点之间的最短路径长度。
var r:real; n,s,t,a,b:longint; f:array[1..100*4+1,1..100*4+1]of
real; c:array[1..100,1..4,1..2]of
longint; ti:array[1..100]of
longint; procedure
make4(x1,y1,x2,y2,x3,y3,i:longint);begin if
(x2-x1)*(x3-x1)+(y2-y1)*(y3-y1)=0 then
begin c[i,4,1]:=x3-x1+x2; c[i,4,2]:=y3-y1+y2; end; if
(x1-x2)*(x3-x2)+(y1-y2)*(y3-y2)=0 then begin c[i,4,1]:=x3+x1-x2;
c[i,4,2]:=y3+y1-y2; end; if
(x2-x3)*(x1-x3)+(y2-y3)*(y1-y3)=0 then begin c[i,4,1]:=-x3+x1+x2;
c[i,4,2]:=-y3+y1+y2; end;end; procedure
init;var i:longint;begin read(s,t,a,b); for i:=1 to s
do
begin
read(c[i,1,1],c[i,1,2],c[i,2,1],c[i,2,2],c[i,3,1],c[i,3,2],ti[i]);
make4(c[i,1,1],c[i,1,2],c[i,2,1],c[i,2,2],c[i,3,1],c[i,3,2],i);
end;end; procedure
getf;var i,j,k,k1,k2:longint;begin for i:=1 to 400
do
for j:=1 to 400 do if
i<>j then
f[i,j]:=maxlongint
else f[i,j]:=0; for k:=1 to s
do
for i:=1 to 4 do for
j:=1 to 4 do
if i<>j then
f[(k-1)*4+i,(k-1)*4+j]:=ti[k]*sqrt(sqr(c[k,i,1]-c[k,j,1])+sqr(c[k,i,2]-c[k,j,2])); for k1:=1 to s
do
for i:=1 to 4 do for
k2:=1 to s do if
k1<>k2 then
for j:=1 to 4 do
f[(k1-1)*4+i,(k2-1)*4+j]:=t*sqrt(sqr(c[k1,i,1]-c[k2,j,1])+sqr(c[k1,i,2]-c[k2,j,2]));end; procedure
dij(x:longint);var temp,min:real; j,mini:longint; d:array[1..400]of
real; mark:array[1..400]of
boolean;begin fillchar(mark,sizeof(mark),0); for j:=1 to 400 do
d[j]:=maxlongint; d[x]:=0; while true
do
begin
min:=maxlongint;
for j:=1 to s*4 do if
(not mark[j])and(d[j]<min) then
begin
min:=d[j];
mini:=j;
end;
mark[mini]:=true; if
(mini-1) div 4=b-1 then
begin
if d[mini]<r then r:=d[mini];
exit;
end; for
j:=1 to s*4 do
if (not mark[j])and(f[mini,j]>0)then
begin
temp:=f[mini,j]+d[mini];
if temp<d[j] then d[j]:=temp;
end;
end;end; procedure
main;var i:longint;begin r:=maxlongint; getf; for i:=1 to 4
do dij((a-1)*4+i); writeln(r:0:1);end; begin read(n); while
n<>0 do
begin
dec(n);
init;
main;
end;end.
Time Limit:10000MS Memory
Limit:65536KTotal Submit:18 Accepted:7
Description
又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。图例 那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。任务: 找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。 输入:文件输入。 输出:输出最小费用,小数点后保留1位。输入格式: 第一行为一个正整数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行,每行一个数据对应测试数据。样例:输入11 10 1 31 1 1 3 3 1 302 5 7 4 5 2 18 6 8 8 11 6 3输出:47.55
Input
Output
Sample
Input
Sample
Output
Source
(1) 首先判断直角的位置:
因为从测试数据文件中读入的三个点的坐标是无序的,因此需判断直角的位置,然后在计算第四个点的坐标。如图,对于线段L1、L2,如果(x1-x2)*(x3-x2)+(y1-y2)*(y3-y2)=0,那么L1
⊥ L2。 (2) 计算(x4,y4): 如图:由x4-x3=x1-x2得x4=x1-x2+x3,同样的y4=y1-y2+y3 (3) 用邻接表或邻接矩阵把各个(机场)点之间的连接关系表示出来。 (4) 计算各条高速铁路的长度l,并求出每个城市中每条高速铁路的总价:Ti * l (5) 计算各条飞机航线的长度l',并求出每条航线的总价:t * l' 用Dijkstra计算各点间的最短路径,求出费用最少的路线。 DIJKSTRA算法算法思想: 设置一个顶点集合S并不断地作贪心选择来扩大这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。DIJKSTRA算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist做必要的修改。一旦S包含了所有V中的顶点,dist就记录了从源到所有其他顶点之间的最短路径长度。
var r:real; n,s,t,a,b:longint; f:array[1..100*4+1,1..100*4+1]of
real; c:array[1..100,1..4,1..2]of
longint; ti:array[1..100]of
longint; procedure
make4(x1,y1,x2,y2,x3,y3,i:longint);begin if
(x2-x1)*(x3-x1)+(y2-y1)*(y3-y1)=0 then
begin c[i,4,1]:=x3-x1+x2; c[i,4,2]:=y3-y1+y2; end; if
(x1-x2)*(x3-x2)+(y1-y2)*(y3-y2)=0 then begin c[i,4,1]:=x3+x1-x2;
c[i,4,2]:=y3+y1-y2; end; if
(x2-x3)*(x1-x3)+(y2-y3)*(y1-y3)=0 then begin c[i,4,1]:=-x3+x1+x2;
c[i,4,2]:=-y3+y1+y2; end;end; procedure
init;var i:longint;begin read(s,t,a,b); for i:=1 to s
do
begin
read(c[i,1,1],c[i,1,2],c[i,2,1],c[i,2,2],c[i,3,1],c[i,3,2],ti[i]);
make4(c[i,1,1],c[i,1,2],c[i,2,1],c[i,2,2],c[i,3,1],c[i,3,2],i);
end;end; procedure
getf;var i,j,k,k1,k2:longint;begin for i:=1 to 400
do
for j:=1 to 400 do if
i<>j then
f[i,j]:=maxlongint
else f[i,j]:=0; for k:=1 to s
do
for i:=1 to 4 do for
j:=1 to 4 do
if i<>j then
f[(k-1)*4+i,(k-1)*4+j]:=ti[k]*sqrt(sqr(c[k,i,1]-c[k,j,1])+sqr(c[k,i,2]-c[k,j,2])); for k1:=1 to s
do
for i:=1 to 4 do for
k2:=1 to s do if
k1<>k2 then
for j:=1 to 4 do
f[(k1-1)*4+i,(k2-1)*4+j]:=t*sqrt(sqr(c[k1,i,1]-c[k2,j,1])+sqr(c[k1,i,2]-c[k2,j,2]));end; procedure
dij(x:longint);var temp,min:real; j,mini:longint; d:array[1..400]of
real; mark:array[1..400]of
boolean;begin fillchar(mark,sizeof(mark),0); for j:=1 to 400 do
d[j]:=maxlongint; d[x]:=0; while true
do
begin
min:=maxlongint;
for j:=1 to s*4 do if
(not mark[j])and(d[j]<min) then
begin
min:=d[j];
mini:=j;
end;
mark[mini]:=true; if
(mini-1) div 4=b-1 then
begin
if d[mini]<r then r:=d[mini];
exit;
end; for
j:=1 to s*4 do
if (not mark[j])and(f[mini,j]>0)then
begin
temp:=f[mini,j]+d[mini];
if temp<d[j] then d[j]:=temp;
end;
end;end; procedure
main;var i:longint;begin r:=maxlongint; getf; for i:=1 to 4
do dij((a-1)*4+i); writeln(r:0:1);end; begin read(n); while
n<>0 do
begin
dec(n);
init;
main;
end;end.
相关文章推荐
- 最短路 之 CODE[VS] 1041 Car的旅行路线 2001年NOIP全国联赛提高组
- 洛谷 P1027 CODE[VS] 1041 [NOIP2001 T4] Car的旅行路线
- VIJOS P1119 (NOIP2001 Problem4):Car的旅行路线 Accepted
- noip2001 car的旅行路线 (floyd求解最短路径长度)
- [NOIP2001][vijos1119]Car的旅行路线(dijkstra堆优化)
- [NOIP 2001提高组T4]Car的旅行路线
- NOIP2001 Car的旅行路线
- [NOIP2001] 提高组 洛谷P1027 Car的旅行路线
- NOIP 2001 Car的旅行路线 解题报告
- NOIP 2001 Car的旅行路线
- [NOIP2001]Car的旅行路线
- NOIP2011提高组-Car的旅行路线
- ACM 95. [NOIP2001] Car的旅行路线(最短路)
- NOIP2001 Car的旅行路线
- [NOIP提高组2001]Car的旅行路线
- 【最短路】【NOIP2001】CAR的旅行路线
- 【NOIP 2001提高组】Car的旅行路线(car.cpp)
- [NOIP2001提高组]CODEVS1014 Car的旅行路线(最短路)
- 【codevs 1041】【vijos P1119】[NOIP提高组2001] Car的旅行路线(最短路)
- 【最短路】【NOIP2001】CAR的旅行路线