首先机器人是并行的;
很容易想到到某个点的最短用时
=max(到这个点的最短路,max(到保护这个点结界所在点的最短用时))
所以我们在做dij的时候,d[j]维护最短路,w[j]维护所有保护这个点结界所在的点的最短用时的最大值
在做最短路松弛的时候,我们肯定是要加一个优先条件即这个点没有结界保护了
注意会爆longint;
1 const inf=9000000000000; 2 var a:array[0..3010,0..3010] of longint; 3 b:array[0..3010,0..3010] of boolean; 4 w,d:array[0..3010] of int64; 5 v:array[0..3010] of boolean; 6 s:array[0..3010] of longint; 7 k,n,m,i,j,x,y:longint; 8 z,p,mid:int64; 9 10 function min(a,b:int64):int64; 11 begin 12 if a>b then exit(b) else exit(a); 13 end; 14 15 function max(a,b:int64):int64; 16 begin 17 if a>b then exit(a) else exit(b); 18 end; 19 20 begin 21 readln(n,m); 22 for i:=1 to n do 23 for j:=1 to n do 24 if i<>j then a[i,j]:=2147483647; 25 for i:=1 to m do 26 begin 27 readln(x,y,z); 28 a[x,y]:=min(a[x,y],z); 29 end; 30 for i:=1 to n do 31 begin 32 read(s[i]); 33 for j:=1 to s[i] do 34 begin 35 read(x); 36 b[i,x]:=true; 37 end; 38 end; 39 d[1]:=0; 40 for i:=2 to n do 41 d[i]:=inf; 42 for i:=1 to n-1 do 43 begin 44 mid:=inf; 45 k:=0; 46 for j:=1 to n do 47 begin 48 z:=max(d[j],w[j]); 49 if not v[j] and (s[j]=0) and (mid>z) then 50 begin 51 mid:=z; 52 k:=j; 53 end; 54 end; 55 if k=0 then break; 56 v[k]:=true; 57 for j:=1 to n do 58 if not v[j] then 59 begin 60 if b[j,k] then 61 begin 62 dec(s[j]); 63 w[j]:=max(w[j],mid); 64 end; 65 d[j]:=min(d[j],mid+a[k,j]); 66 end; 67 end; 68 writeln(max(d[n],w[n])); 69 end.