計算幾何 Car的旅行路線 NOIP2

2021-06-28 13:26:10 字數 4420 閱讀 2961

car的旅行路線【noip2001提高組】

time limit:10000ms  memory limit:65536k

total 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 3

1 1 1 3 3 1 30

2 5 7 4 5 2 1

8 6 8 8 11 6 3

輸出:47.55

input

output

sample input

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

sample output

47.6

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]

begin

min:=d[j];

mini:=j;

end;

mark[mini]:=true;

if (mini-1) div 4=b-1 then

begin

if 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

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.

Car的旅行路線

題目描述 description 又到暑假了,住在城市a的car想和朋友一起去城市b旅遊。她知道每個城市都有四個飛機場,分別位於乙個矩形的四個頂點上,同乙個城市中兩個機場之間有一條筆直的高速鐵路,第i個城市中高速鐵路了的單位里程 為ti,任意兩個不同城市的機場之間均有航線,所有航線單位里程的 均為t...

Car的旅行路線

題d car的旅行路線 時間限制 1 記憶體限制 128 mb 提交 1 解決 0 標籤標籤已被遮蔽 提交狀態 討論版 題目描述 又到暑假了,住在城市a的car想和朋友一起去城市b旅遊。她知道每個城市都有四個飛機場,分別位於乙個矩形的四個頂點上,同乙個城市中兩個機場之間有一 條筆直的高速鐵路,第i個...

Car的旅行路線

又到暑假了,住在城市a的car想和朋友一起去城市b旅遊。她知道每個城市都有四個飛機場,分別位於乙個矩形的四個頂點上,同乙個城市中兩個機場之間有一條筆直的高速鐵路,第i個城市中高速鐵路了的單位里程 為ti,任意兩個不同城市的機場之間均有航線,所有航線單位里程的 均為t。那麼car應如何安排到城市b的路...