您的位置:首页 > 其它

COGS 497——奶牛派对

2015-10-15 23:52 501 查看
奶牛派对

我们发现每头牛需要走的路程即为它到x的最短路+x到它的最短路。

转化:

于是这道题变成了一道典型的单源最短路问题,只需求出每个点到x的最短路dl,以及从x到此点的最短路d2,然后去找max(dl+d2)即可。

效率分析:

使用dijsktra算法,时间复杂度为O(n^2)。

【我的程序】

type aa=array[1..1000,1..1000] of longint;
var
n,m,x,a,b,t,i,j,k,min,max:longint;
map1,map2:aa;
ans:array[1..1000] of longint;
f:array[1..1000] of boolean;
d:array[1..1000] of longint;
procedure dijkstra(map:aa);
begin
for i:=1 to n do
begin d[i]:=map[x,i]; f[i]:=false; end;
f[x]:=true;
for i:=2 to n do
begin
min:=maxlongint; k:=0;
for j:=1 to n do
if (not f[j]) and (d[j]<min) then
begin min:=d[j]; k:=j; end;
if (k=0) or (min=maxlongint) then exit;
f[k]:=true;
for j:=1 to n do
if (not f[j]) and (d[k]+map[k,j]<d[j])
then d[j]:=d[k]+map[k,j];
end;
for i:=1 to n do ans[i]:=ans[i]+d[i];
end;
begin
assign(input,'party.in');
reset(input);
assign(output,'party.out');
rewrite(output);
readln(n,m,x);
for i:=1 to n do
for j:=1 to n do
if i=j then begin map1[i,j]:=0; map2[i,j]:=0; end
else begin map1[i,j]:=maxlongint div 2; map2[i,j]:=maxlongint div 2; end;
for i:=1 to m do
begin
readln(a,b,t);
map1[a,b]:=t;
map2[b,a]:=t;//if (map[a,b]>t) or (map[a,b]=0) then map[a,b]:=t;
end;
dijkstra(map1);
dijkstra(map2);
for i:=1 to n do if ans[i]>max then max:=ans[i];
writeln(max);
end.


【老师给的标程】

const
maxn=1000;
maxm=100000;
var
n,m,X,i,j,sum,ans:longint;
path:array[1..2,0..maxn,0..maxn]of Longint;
dis:array[1..2,0..maxn]of Longint;
v:array[0..maxn]of boolean;
procedure Init;
var
A,b,c:Longint;
begin
readln(n,m,X);
for i :=1 to n do
for j:=1 to n do
begin
path[1,i,j]:=maxm;
path[2,i,j]:=maxm;
end;
for i := 1 to m do
begin
readln(A,b,c);
If path[1,A,b] > c then
begin
path[1,A,b] := c;
path[2,b,A] := c;
end;
end;
end;
procedure dij(k:longint);
var
min,minj,i,j,t:Longint;
begin
fillchar(v,sizeof(v),false);
for i := 1 To n do
If path[k,X,i] <> maxm then dis[k,i] := path[k,X,i]
else dis[k,i] := maxm;
v[x] := true;
dis[k,x] := 0;
for i := n-1 downto 1 do
begin
min:=maxm;
for j := 1 to n do
if (dis[k,j] < min)And(not v[j]) then
begin
min := dis[k,j];
minj := j;
end;
if min<>maxm then
begin
v[minj] := true;
j:=minj;
for t := 1 to n do
If (dis[k,j]+path[k,j,t] < dis[k,t])And(not v[t]) Then
dis[k,t] := dis[k,j]+path[k,j,t];
end;
end;
end;
procedure main;
begin
dij(1);
dij(2);
Ans:=0;
for i := 1 to n do
begin
sum := dis[1,i]+dis[2,i];
If (sum>ans)and(i<>X) then ans:=sum;
end;
end;
procedure Ouit;
begin
Writeln(ans);
end;
begin
Init;
main;
Ouit;
end.


【考试时错误的做法】还是没有真正理解dijkstra

var
i,j,n,m,x,k1,k2,w,min,k,max:longint;
a:array[1..1000,1..1000] of longint;
d,ans:array[1..1000] of longint;
f:array[1..1000] of boolean;
procedure dijkstra1;
begin
for i:=1 to n do
begin  d[i]:=a[x,i]; f[i]:=false; end;
f[x]:=true;
for i:=2 to n do
begin
min:=maxlongint;  k:=0;
for j:=1 to n do
if (not f[j]) and (d[j]<min)  then
begin
min:=d[j]; k:=j;
end;
if  (k=0)or(min=maxint) then exit;
f[k]:=true;
for j:=1 to n do
if (not f[j]) and (d[k]+a[k,j]<d[j]) then d[j]:=d[k]+a[k,j];
end;
end;
procedure dijkstra2;
begin
for i:=1 to n do
begin  d[i]:=a[i,x]; f[i]:=false; end;
f[x]:=true;
for i:=2 to n do
begin
min:=maxlongint;  k:=0;
for j:=1 to n do
if (not f[j]) and (d[j]<min)  then
begin
min:=d[j]; k:=j;
end;
if  (k=0)or(min=maxint) then exit;
f[k]:=true;
for j:=1 to n do
if (not f[j]) and (d[k]+a[k,j]<d[j]) then d[j]:=d[k]+a[k,j];
end;
end;
begin
readln(n,m,x);
for i:=1 to n do
for j:=1 to n do
if i=j then a[i,j]:=0 else a[i,j]:=maxlongint div 2;
for i:=1 to m do
begin
readln(k1,k2,w);
a[k1,k2]:=w;
end;
dijkstra1;
for i:=1 to n do if i<>x then begin ans[i]:=ans[i]+d[i];  end;
dijkstra2;     max:=-maxint;
for i:=1 to n do if i<>x then
begin
ans[i]:=ans[i]+d[i];
if ans[i]>max then max:=ans[i];
end;
writeln(max);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: