题目大意
N头牛要去参加一场在编号为x(1<=x<=n)的牛的农场举行的派对(1<=N<=1000),有M(1<=m<=100000)条有向道路,每条路长ti(1<=ti<=100);
每头牛都必须参加完派对后回到家,每头牛都会选择最短路径,求这n个牛的最短路径(一个来回)中最长的一条的长度。
特别提醒:可能有权值不同的重边。
分析
这一眼看上去就是一个最短路。
注意,因为是有向图,所以从家到x农场的最短路和从x农场到家的最短路是不一样的。
所以,只用先把x到其他点的最短路求出来,再把边反向链接,再求一次x到其他点的最短路。两次结果相加得数最大的,就是结果。
反思
要设置好数组,jpwang就是因为数组没设好错的。
代码
const
maxe=2000;
maxv=200000;
type
arr=record
x,y,w:longint;
next:longint;
end;
var
a:array[1..maxv] of arr;
ls:array[1..maxe] of longint;
v,d,f,ans:array[1..maxe] of longint;
i,j,k,w:longint;
n,m,st:longint;
nm,max:longint;
procedure spfa;
var
i,j,k:longint;
head,tail:longint;
begin
head:=0; tail:=1;
fillchar(v,sizeof(v),0);
fillchar(d,sizeof(d),0);
fillchar(f,sizeof(f),$7f);
v[st]:=1;
d[1]:=st;
f[st]:=0;
repeat
head:=head+1;
j:=d[head];
i:=ls[j];
while i<>0 do
begin
with a[i] do
begin
if f[x]+w<f[y]
then
begin
f[y]:=f[x]+w;
if v[y]=0
then
begin
tail:=tail+1;
v[y]:=1;
d[tail]:=y;
end;
end;
i:=next;
end;
end;
v[j]:=0;
until head=tail;
end;
procedure add(x,y,w:longint);
begin
nm:=nm+1;
a[nm].x:=x;
a[nm].y:=y;
a[nm].w:=w;
a[nm].next:=ls[x];
ls[x]:=nm;
end;
begin
readln(n,m,st);
fillchar(ls,sizeof(ls),0);
for i:=1 to m do
begin
readln(j,k,w);
add(j,k,w);
end;
spfa;
for i:=1 to n do
ans[i]:=f[i];
fillchar(ls,sizeof(ls),0);
for i:=1 to nm do
begin
with a[i] do
begin
j:=x;
x:=y;
y:=j;
next:=ls[x];
ls[x]:=i;
end;
end;
spfa;
for i:=1 to n do
ans[i]:=f[i]+ans[i];
max:=0;
for i:=1 to n do
if max<ans[i]
then max:=ans[i];
write(max);
end.