最短路径问题

来源:互联网 发布:电子贺卡制作软件 编辑:程序博客网 时间:2024/05/17 02:02

最短路径问题

Time Limit:10000MS  Memory Limit:65536K
Total Submit:247 Accepted:134
Case Time Limit:1000MS

Description

平面上有n个点(N<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点直线的距离。现在的任务是找出从一点到另一点之间的最短路径。

Input

输入文件short.in,共有n+m+3行,其中:
第一行为一个整数n。
第2行到第n+1行(共n行),每行的两个整数x和y,描述一个点的坐标(以一个空格隔开)。
第n+2行为一个整数m,表示图中的连线个数。
此后的m行,每行描述一条连线,由两个整数I,j组成,表示第i个点和第j个点之间有连线。
最后一行:两个整数s和t,分别表示源点和目标点。

Output

输出文件short.out仅一行,一个实数(保留两位小数),表示从S到T的最短路径的长度。

Sample Input

50 0 2 02 20 23 151 21 31 42 53 51 5

Sample Output

3.41

(1)             假设用带权的邻接矩阵a来表示带权有向图,a[i,j]表示弧<Vi,Vj>上的权值。若<Vi,Vj>不存在,则置a[I,j]为无穷大。S为已找到从V出发的最短路径的终点的集合,它的初始状态为空集。那么,从v0出发到图上其余各顶点(终点)Vi可能达到的最短路径长度的初值为:dist[I]:=a[v0,I]。

(2)             


选择Vj,使得d[j]:=min{dist[I],Vi∈V-S}, Vj就是当前求得的一条从V出发的最短路径的终点。令S=S∪{J}。

(3)             修改从Vj 出发到集合V-S上任一顶点Vk可达的最短路径长度。如果d[j]+a[j,k]<dist[k],则修改d[k]为d[k]=d[j]+a[j,k]。

(4)             重复操作(2)、(3)共n-1次。由此求得从v 到图上其余各顶点的最短路径是依路径长度递增的序列。

  • const  maxn=100;var  a:array[0..maxn,0..maxn] of real;  x,y,v:array[0..maxn] of longint;  d:array[0..maxn] of real;  i,j,k,n,m,s,t,ans:longint;function way(x1,y1,x2,y2:longint):real;begin  way:=sqrt(sqr(x1-x2)+sqr(y1-y2));end;procedure dij(x:longint);var  i,j,k:longint;  min:real;begin  for i:=1 to n do    d[i]:=a[x,i];  v[x]:=1;  repeat    min:=maxlongint;    k:=0;    for i:=1 to n do      if (v[i]=0) and (d[i]<min)        then begin               k:=i;               min:=d[i];             end;    v[k]:=1;    for i:=1 to n do      if (v[i]=0) and (a[k,i]+d[k]<d[i]) and (a[k,i]>0)        then d[i]:=a[k,i]+d[k];  until k=0;end;begin  readln(n);  for i:=1 to n do    readln(x[i],y[i]);  readln(m);  for i:=1 to n do    for j:=1 to n do      a[i,j]:=maxlongint;  for i:=1 to m do    begin      readln(j,k);      a[j,k]:=way(x[j],y[j],x[k],y[k]);      a[k,j]:=a[j,k];    end;  readln(s,t);  dij(s);  writeln(d[t]:0:2);end.

1 0
原创粉丝点击