被破坏的电力系统

【题目描述】

一次猛烈的雷暴把农场里一些连接电力网格的电线损坏了。约翰有一张包含全部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.

猜你喜欢

转载自www.cnblogs.com/Dawn-Star/p/9181539.html