1. 题目 Road in Genoa
题目描述
48 B.C.
Caesar远征高卢回来后,对你大加赞赏,他亲自来到Genoa视察。
Genoa在你的建设下变得无比繁荣,由于财政收入的增加,你为城市修建了交通系统。古罗马的交通系统由两部分组成——Dirt Road和Rome Road。两个路口间只可能是其中一种道路。在Rome Road上可以驾驶马车,而在Dirt Road上则不行。由于修建道路是一项浩大的工程,使得你无法将整个城市用Rome Road连接起来。
现在Caesar已经到达码头,他要求去你家参观。Caesar由一个癖好,喜欢坐车而不喜欢走路。所以Caesar走Dirt Road时的不满值要比走Rome Road时大。
为了不让Caesar过于不满而罢免你的职位,请设计路线使得Caesar的不满值最小。
输入数据
输入数据第一行有两个实数,分别表示走Dirt Road和Rome Road一个单位长度时Caesar的不满值。接下来是一个整数N(N<=1000),代表路口总数。接下来有N行,每行一组实数(x,y)分别描述这N个路口的坐标。接下来有若干行,每行一组整数(i,j),表示第i个路口与第j个路口间为Rome Road,以0 0结束。最后两行,每行一对实数,分别描述码头和你家的坐标。
输出数据
输出Caesar从码头到你家的最小不满值,保留4位小数
样例输入
100.0 2.0
2
1.0 0.0
2.0 1.0
1 2
0 0
0.0 0.0
2.0 2.0
样例输出
202.8284
2. 题目实质 让你求两点之间的最短路。
3. 算法
想当然耳,图论。
就是这里的建模比较古怪。
虚拟出两个节点(起点和终点),然后任意两点间联通(连一条边),如果这两点间那一条边是 Rome Road ,则权值为距离乘 Rome Road 的不满值,其他的为距离乘 Dirt Road 的不满值。
两点之间距离公式: sqrt(sqr(x1-x2)+sqr(y1-y2)) 。
然后跑一遍最短路,因为他的数据实在是太小了,所以用什么算法都不会超时。
4. 注意事项
不要忘了虚拟接点这一招。
5. 时空复杂度
看你跑最短路用的是什么。
6. 程序代码
SPFA: 艾 FHAI (pascal)
var
lk:array[-2..1005,1..2]of real;
b:array[0..1003,0..1003]of real;
d:array[-2..1003]of real;
q:array[1..10000000]of longint;
v:array[-2..1005]of boolean;
r:array[0..1000,0..1000]of boolean;
sx,ex,ey,x,y,dc,rc,sy:real;
la,i,n,j,t,now,ta,he,s,e:longint;
begin
assign(input,'input.txt');reset(input);
assign(output,'output.txt');rewrite(output);
fillchar(v,sizeof(v),false);
readln(dc,rc);
readln(n);
for i:=1 to n do
begin
readln(x,y);
inc(la);
lk[la,1]:=x;
lk[la,2]:=y;
end;
i:=1;j:=1;
for i:=1 to la+2 do
for j:=1 to la+2 do
b[i,j]:=-1;
while (i<>0) and (j<>0) do
begin
readln(i,j);
b[i,j]:=rc;
b[j,i]:=rc;
end;
readln(sx,sy);
inc(la);lk[la,1]:=sx;lk[la,2]:=sy;s:=la;
readln(ex,ey);
inc(la);lk[la,1]:=ex;lk[la,2]:=ey;e:=la;
for i:=1 to la do
for j:=1 to la do
if i<>j then
begin
if b[i,j]=rc then
begin
b[i,j]:=b[i,j]*sqrt(sqr(lk[i,1]-lk[j,1])+sqr(lk[i,2]-lk[j,2]));
b[j,i]:=b[i,j];
end
else if b[i,j]=-1 then
begin
b[i,j]:=dc*sqrt(sqr(lk[i,1]-lk[j,1])+sqr(lk[i,2]-lk[j,2]));
b[j,i]:=b[i,j];
end;
end
else b[i,j]:=0;
for i:=1 to la do
d[i]:=100000000;
q[1]:=s;d[s]:=0;
he:=0;ta:=1;v[s]:=true;
while he<=ta do
begin
inc(he);
now:=q[he];
for i:=1 to la do
if i<>now then
begin
if d[i]>d[now]+b[i,now] then d[i]:=d[now]+b[i,now];
if not v[i] then
begin
v[i]:=false;
inc(ta);
q[ta]:=i;
end;
end;
v[now]:=false;
end;
write(d[e]:0:4);
close(input);close(output);
end.
7. 囧囧的惊残孤梦
为什么,为什么我没有想到建模?怎么可以这样?
唉唉,没的说了,回去复习图轮