单元最短路径
给定一个带权 图 ,求某点到某点的最短距离。
算法
将图G中所有的顶点v分成两个顶点集合a & b。以v为源点已经确定了最短路径的终点并入a集合中,a初始时只含顶点v,b则是尚未确定到源点v最短路径的顶点集合。然后每次从b集合中选择a集合点中到b路径最短的那个点,并加入到集合a中,并把这个点从集合b删除,直到b集合为空为止。
代码如下:
Var s,e,n,m,a,b,c,i,j:longint;
f:array[0..1005] of boolean;
d:array[0..1005] of longint;
w:array[0..1005,0..1005] of longint;
procedure dj(x:longint);
Var i,j,k,pos,min:longint;
Begin
f[x]:=true;
d:=w[x];
for i:=1 to n-1 do
Begin
min:=maxlongint;
for j:=1 to n do
Begin
if (not f[j]) and (d[j]<min) then
Begin
min:=d[j];
pos:=j;
end;
end;
f[pos]:=true;
for j:=1 to n do
Begin
if (not f[j]) and (d[pos]+w[pos,j]<d[j]) then
Begin
d[j]:=w[pos,j]+d[pos];
end;
end;
end;
end;
Begin
read(n,m);
for i:=1 to n do
Begin
for j:=1 to n do
Begin
w[i,j]:=100000;
end;
end;
for i:=1 to m do
Begin
read(a,b,c);
w[a,b]:=c;
w[b,a]:=c;
end;
read(s,e);
dj(s);
write(d[e]);
end.
算法
此算法使用邻接矩阵来储存边,通过考虑最佳子路径来得到最佳路径。 从任意一条单边路径开始。所有两点之间的距离是边的权,或者无穷大,如果两点之间没有边相连。对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短,如果是,那么更新它。
代码如下:
Var i,j,k,a,b,n,m,s,e:longint;
w:array[0..1000,0..1000] of longint;
Begin
read(n,m);
for i:=1 to n do
Begin
for j:=1 to n do
Begin
if i<>j then w[i,j]:=maxint
else w[i,j]:=0;
end;
end;
for i:=1 to m do
Begin
read(a,b,w[a,b]);
w[b,a]:=w[a,b];
end;
read(s,e);
for k:=1 to n do
Begin
for i:=1 to n do
Begin
for j:=1 to n do
Begin
if w[i,k]+w[k,j]<w[i,j] then
Begin
w[i,j]:=w[i,k]+w[k,j];
end;
end;
end;
end;
write(w[s,e]);
end.