COGS 497——奶牛派对
我们发现每头牛需要走的路程即为它到x的最短路+x到它的最短路。
转化:
于是这道题变成了一道典型的单源最短路问题,只需求出每个点到x的最短路dl,以及从x到此点的最短路d2,然后去找max(dl+d2)即可。
效率分析:
使用dijsktra算法,时间复杂度为O(n^2)。
【我的程序】
1 type aa=array[1..1000,1..1000] of longint; 2 var 3 n,m,x,a,b,t,i,j,k,min,max:longint; 4 map1,map2:aa; 5 ans:array[1..1000] of longint; 6 f:array[1..1000] of boolean; 7 d:array[1..1000] of longint; 8 procedure dijkstra(map:aa); 9 begin 10 for i:=1 to n do 11 begin d[i]:=map[x,i]; f[i]:=false; end; 12 f[x]:=true; 13 for i:=2 to n do 14 begin 15 min:=maxlongint; k:=0; 16 for j:=1 to n do 17 if (not f[j]) and (d[j]<min) then 18 begin min:=d[j]; k:=j; end; 19 if (k=0) or (min=maxlongint) then exit; 20 f[k]:=true; 21 for j:=1 to n do 22 if (not f[j]) and (d[k]+map[k,j]<d[j]) 23 then d[j]:=d[k]+map[k,j]; 24 end; 25 for i:=1 to n do ans[i]:=ans[i]+d[i]; 26 end; 27 begin 28 assign(input,'party.in'); 29 reset(input); 30 assign(output,'party.out'); 31 rewrite(output); 32 readln(n,m,x); 33 for i:=1 to n do 34 for j:=1 to n do 35 if i=j then begin map1[i,j]:=0; map2[i,j]:=0; end 36 else begin map1[i,j]:=maxlongint div 2; map2[i,j]:=maxlongint div 2; end; 37 for i:=1 to m do 38 begin 39 readln(a,b,t); 40 map1[a,b]:=t; 41 map2[b,a]:=t;//if (map[a,b]>t) or (map[a,b]=0) then map[a,b]:=t; 42 end; 43 dijkstra(map1); 44 dijkstra(map2); 45 for i:=1 to n do if ans[i]>max then max:=ans[i]; 46 writeln(max); 47 end.
【老师给的标程】
1 const 2 maxn=1000; 3 maxm=100000; 4 var 5 n,m,X,i,j,sum,ans:longint; 6 path:array[1..2,0..maxn,0..maxn]of Longint; 7 dis:array[1..2,0..maxn]of Longint; 8 v:array[0..maxn]of boolean; 9 procedure Init; 10 var 11 A,b,c:Longint; 12 begin 13 readln(n,m,X); 14 for i :=1 to n do 15 for j:=1 to n do 16 begin 17 path[1,i,j]:=maxm; 18 path[2,i,j]:=maxm; 19 end; 20 for i := 1 to m do 21 begin 22 readln(A,b,c); 23 If path[1,A,b] > c then 24 begin 25 path[1,A,b] := c; 26 path[2,b,A] := c; 27 end; 28 end; 29 end; 30 procedure dij(k:longint); 31 var 32 min,minj,i,j,t:Longint; 33 begin 34 fillchar(v,sizeof(v),false); 35 for i := 1 To n do 36 If path[k,X,i] <> maxm then dis[k,i] := path[k,X,i] 37 else dis[k,i] := maxm; 38 v[x] := true; 39 dis[k,x] := 0; 40 for i := n-1 downto 1 do 41 begin 42 min:=maxm; 43 for j := 1 to n do 44 if (dis[k,j] < min)And(not v[j]) then 45 begin 46 min := dis[k,j]; 47 minj := j; 48 end; 49 if min<>maxm then 50 begin 51 v[minj] := true; 52 j:=minj; 53 for t := 1 to n do 54 If (dis[k,j]+path[k,j,t] < dis[k,t])And(not v[t]) Then 55 dis[k,t] := dis[k,j]+path[k,j,t]; 56 end; 57 end; 58 end; 59 procedure main; 60 begin 61 dij(1); 62 dij(2); 63 Ans:=0; 64 for i := 1 to n do 65 begin 66 sum := dis[1,i]+dis[2,i]; 67 If (sum>ans)and(i<>X) then ans:=sum; 68 end; 69 end; 70 procedure Ouit; 71 begin 72 Writeln(ans); 73 end; 74 begin 75 Init; 76 main; 77 Ouit; 78 end.
【考试时错误的做法】还是没有真正理解dijkstra
1 var 2 i,j,n,m,x,k1,k2,w,min,k,max:longint; 3 a:array[1..1000,1..1000] of longint; 4 d,ans:array[1..1000] of longint; 5 f:array[1..1000] of boolean; 6 procedure dijkstra1; 7 begin 8 for i:=1 to n do 9 begin d[i]:=a[x,i]; f[i]:=false; end; 10 f[x]:=true; 11 for i:=2 to n do 12 begin 13 min:=maxlongint; k:=0; 14 for j:=1 to n do 15 if (not f[j]) and (d[j]<min) then 16 begin 17 min:=d[j]; k:=j; 18 end; 19 if (k=0)or(min=maxint) then exit; 20 f[k]:=true; 21 for j:=1 to n do 22 if (not f[j]) and (d[k]+a[k,j]<d[j]) then d[j]:=d[k]+a[k,j]; 23 end; 24 end; 25 procedure dijkstra2; 26 begin 27 for i:=1 to n do 28 begin d[i]:=a[i,x]; f[i]:=false; end; 29 f[x]:=true; 30 for i:=2 to n do 31 begin 32 min:=maxlongint; k:=0; 33 for j:=1 to n do 34 if (not f[j]) and (d[j]<min) then 35 begin 36 min:=d[j]; k:=j; 37 end; 38 if (k=0)or(min=maxint) then exit; 39 f[k]:=true; 40 for j:=1 to n do 41 if (not f[j]) and (d[k]+a[k,j]<d[j]) then d[j]:=d[k]+a[k,j]; 42 end; 43 end; 44 begin 45 readln(n,m,x); 46 for i:=1 to n do 47 for j:=1 to n do 48 if i=j then a[i,j]:=0 else a[i,j]:=maxlongint div 2; 49 for i:=1 to m do 50 begin 51 readln(k1,k2,w); 52 a[k1,k2]:=w; 53 end; 54 dijkstra1; 55 for i:=1 to n do if i<>x then begin ans[i]:=ans[i]+d[i]; end; 56 dijkstra2; max:=-maxint; 57 for i:=1 to n do if i<>x then 58 begin 59 ans[i]:=ans[i]+d[i]; 60 if ans[i]>max then max:=ans[i]; 61 end; 62 writeln(max); 63 end.