被破坏的电力系统
【题目描述】
一次猛烈的雷暴把农场里一些连接电力网格的电线损坏了。约翰有一张包含全部N(2≤N≤1000)个电力点的地图,电力点的编号是1到N,位置是平面直角坐标系中的坐标x_i,y_i (-100,000 <= x_i <=100000; -100,000 <= y_i <= 100,000)。
雷暴后剩下了W (1 <= W <= 10,000)条电线,每条连接了一对电力点只Pi and Pj (1 <= Pi <= N; 1 <= Pj <= N)。
他现在需要将电力从1号电力点运送到N号电力点,也就是说电流可以通过一些电线从1号电力点流到N号电力点,可以流过一些作为中介的电力点。
给出N个电力点的位置以及剩下的电线的列表,使得电力可以从1号电力点运送到N号电力点,求出需要增加的电线的最短长度,所有电线的长度都不能超过一个实数M (0.0 < M<= 200,000.0)。
例如下图的左侧是在雷暴之后的9个电力点和3条电线的地图,对于当前的任务,AI =2众最优的增加电线的方案是在4号和6号电力点以及6号和9号电力点间增加电线。
After the storm Optimally reconnected
3 . . . 7 9 . . . . . 3 . . . 7 9 . . . . .
/
2 . . 5 6 . . . . . . 2 . . 5 6 . . . . . .
/
1 2-3-4 . 8 . . . . . 1 2-3-4 . 8 . . . . .
| |
0 1 . . . . . . . . . 0 1 . . . . . . . . .
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
增加电线的总长度为1.414213562 + 1.414213562 = 2.828427124。
【输入格式】
* 第1行输入两个用空格分开的数N和w。
* 第2行输入一个实数M。
* 第3到N+2行每行包含两个正整数x_i和y_i。
* 第N+3到N+2+W行每行两个用空格分隔的数Pi和Pj。
【输出格式】
一个整数,实际结果乘以1000后取整,请不要进行任何的4舍5入工作,如果不可能送到,则输出-1。
【分析】
先算出欧几里得距离,在用最短路,算出答案就可以了,比较的简单,dijstra,spfa都可以。
【代码】
1 var 2 boo:array[1..3000]of boolean; 3 x,y:array[1..3000]of longint; 4 l:array[1..3000]of real; 5 d:array[1..3000,1..3000]of real; 6 n,w,i,j,k,a,b:longint; 7 t,m:real; 8 function calc(a,b:longint):real; 9 begin 10 exit(sqrt(sqr(x[a]-x[b])+sqr(y[a]-y[b]))); 11 end; 12 begin 13 fillchar(boo,sizeof(boo),false); 14 read(n,w,m); 15 for i:=1 to n do 16 for j:=1 to n do 17 d[i,j]:=maxlongint; 18 for i:=1 to n do 19 read(x[i],y[i]); 20 for i:=1 to w do begin 21 read(a,b); 22 t:=calc(a,b); 23 d[a,b]:=0; 24 d[b,a]:=0; 25 end; 26 for i:=1 to n do 27 for j:=1 to n do 28 if d[i,j]<>0 29 then begin 30 t:=calc(i,j); 31 if t<m then begin 32 d[i,j]:=t; 33 d[j,i]:=t; 34 end; 35 end; 36 for i:=1 to n do 37 l[i]:=maxlongint; 38 l[1]:=0; 39 for i:=2 to n do begin 40 k:=-1; 41 for j:=1 to n do 42 if not boo[j]and((k=-1)or(l[k]>l[j])) 43 then k:=j; 44 boo[k]:=true; 45 for j:=1 to n do 46 if not boo[j]and(l[k]+d[k,j]<l[j]) 47 then l[j]:=l[k]+d[k,j]; 48 end; 49 if l[n]=maxlongint then write('-1') 50 else write(trunc(l[n]*1000)); 51 end.