题目大意:求无向图的次短路。
分析:
在起点终点各求一次最短路,枚举边,通过该边的最短路为其权值加上到起点和终点最短路之和,找到最短但又比最短路长的路径。
代码:

program block;
type
point=^node;
node=record
v,c:longint; next:point; end;
var
a:array[0..5000]of point;
dis:array[0..5000,1..2]of longint;
q:array[0..5000]of longint;
g:array[0..5000]of boolean;
e:array[0..100000,1..3]of longint;
n,i,m,x,y,v,ans:longint; p:point;
procedure add(x,y,c:longint);
var p:point;
begin
new(p); p^.v:=y; p^.c:=c; p^.next:=a[x]; a[x]:=p;
end;
procedure spfa(s,d,l:longint);
var i,h,t,u,v,k:longint;
begin
fillchar(g,sizeof(g),false);
for i:=1 to n do dis[i,l]:=maxlongint div 3; dis[s,l]:=0; g[s]:=true;
h:=0; t:=1; q[1]:=s;
while h<t do
begin
inc(h); u:=q[h]; g[u]:=false; new(p); p:=a[u];
while p<>nil do
begin
v:=p^.v;
if dis[v,l]>dis[u,l]+p^.c then
begin
dis[v,l]:=dis[u,l]+p^.c;
if g[v]=false then begin g[v]:=true; inc(t);q[t]:=v;end;
end;
p:=p^.next;
end;
end;
end;
begin
assign(input,'block.in');
reset(input);
assign(output,'block.out');
rewrite(output);
readln(n,m);
for i:=1 to m do
begin
readln(x,y,v); e[i,1]:=x; e[i,2]:=y; e[i,3]:=v;
add(x,y,v); add(y,x,v);
end;
spfa(1,n,1); spfa(n,1,2); ans:=maxlongint;
for i:=1 to m do
begin
v:=dis[e[i,1],1]+dis[e[i,2],2]+e[i,3]; if (v<ans)and(v>dis[n,1]) then ans:=v;
v:=dis[e[i,2],1]+dis[e[i,1],2]+e[i,3]; if (v<ans)and(v>dis[n,1]) then ans:=v;
end;
writeln(ans);
close(input); close(output);
end.
来源:https://www.cnblogs.com/qtyytq/p/5328597.html
