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

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