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.

 

posted @ 2015-10-15 23:52  ZJQCation  阅读(558)  评论(0编辑  收藏  举报