题意/Description:
N头牛要去参加一场在编号为x(1<=x<=n)的牛的农场举行的派对(1<=N<=1000),有M(1<=m<=100000)条有向道路,每条路长ti(1<=ti<=100);
每头牛都必须参加完派对后回到家,每头牛都会选择最短路径,求这n个牛的最短路径(一个来回)中最长的一条的长度。特别提醒:可能有权值不同的重边。
读入/Input:
第1行: N,M,X;
第2~m+1行: Ai,Bi,Ti,表示有一条从Ai到Bi的路,长度为Ti.
输出/Output:
最长最短路的长度。
题解/solution:
正和反各做一遍SPFA,用一个数组累加,找最大值。
代码/Code:
const
maxE=20001;
maxV=200001;
type
arr=record
x,y,w:longint;
next:longint;
end;
var
nm,n,m,xy,max:longint;
tu:array [0..maxV] of arr;
ls,v,d,f,ans:array [0..maxE] of longint;
procedure add(o,p,op:longint);
begin
inc(nm);
with tu[nm] do
begin
x:=o; y:=p; w:=op;
next:=ls[o];
ls[o]:=nm;
end;
end;
procedure spfa;
var
he,ta,i,j:longint;
begin
he:=0; ta:=1;
v[xy]:=1; d[1]:=xy; f[xy]:=0;
repeat
inc(he);
j:=d[he];
i:=ls[j];
while i<>0 do
with tu[i] do
begin
if f[x]+w<f[y] then
begin
f[y]:=f[x]+w;
if v[y]=0 then
begin
inc(ta);
v[y]:=1;
d[ta]:=y;
end;
end;
i:=next;
end;
v[j]:=0;
until he=ta;
end;
procedure init1;
var
i,xx,yy,zz:longint;
begin
readln(n,m,xy);
for i:=1 to m do
begin
readln(xx,yy,zz);
add(xx,yy,zz);
end;
fillchar(v,sizeof(v),0);
fillchar(d,sizeof(d),0);
fillchar(f,sizeof(f),$7f div 3);
spfa;
end;
procedure init2;
var
i,t:longint;
begin
fillchar(ls,sizeof(ls),0);
for i:=1 to nm do
with tu[i] do
begin
t:=x; x:=y; y:=t;
next:=ls[x];
ls[x]:=i;
end;
fillchar(v,sizeof(v),0);
fillchar(d,sizeof(d),0);
fillchar(f,sizeof(f),$7f div 3);
end;
procedure main;
var
i:longint;
begin
max:=0;
for i:=1 to n do
ans[i]:=f[i];
init2;
spfa;
for i:=1 to n do
if max<ans[i]+f[i] then max:=ans[i]+f[i];
write(max);
end;
begin
init1;
main;
end.