Party_纪中_1328
题目大意
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.