POJ 3026 [Borg Maze]

本文介绍了一种解决算法竞赛中特定问题的方法,通过BFS算法计算每两个点之间的最短距离,再利用Prim算法找到最小生成树。文章详细展示了使用记录类型、数组和过程进行数据管理和算法实现的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  这个题应该先求出每两个点对的最短距离(BFS),然后求最小生成树(Prim),表示BFS写得很疵,没有很好地注意边界条件

虽然AC了……

Type
lzy=record
x,y:longint;
end;
Kudo=record
pos,step,x,y:longint;
end;
Const
dx:array[1..4]of -1..1=(1,-1,0,0);
dy:array[1..4]of -1..1=(0,0,-1,1);
Var
map:array[-1..500,-1..500]of char;
spot,dis:array[-1..500,-1..500]of longint;
link:array[-1..50*500]of lzy;
lowcost:array[1..50*500]of longint;
vis:array[-1..500,-1..500]of boolean;
q:array[-1..50*50000]of kudo;
m,n,p,i,j,fuck,fucks:longint;
Procedure init;
var
i,j:longint;
ch:char;
begin
readln(m,n);
p:=0;
fillchar(spot,sizeof(spot),0);
fillchar(dis,sizeof(dis),$3f);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(map[i,j]);
if (map[i,j]='A')or(map[i,j]='S') then
begin
inc(p);
spot[i,j]:=p;
link[p].x:=i;
link[p].y:=j;
end;
end;
readln;
end;
end;
Procedure refresh(x1,y1,x2,y2,tmp:longint);
var
left,right:longint;
begin
left:=spot[x1,y1];
right:=spot[x2,y2];
if tmp<dis[left,right] then
begin
dis[left,right]:=tmp;
dis[right,left]:=tmp;
end;
end;
Procedure getdis(stx,sty:longint);
var
head,tail,i,j:longint;
pre:Kudo;
tmp:lzy;
ch:char;
begin
head:=0;
tail:=1;
fillchar(vis,sizeof(vis),false);
q[1].pos:=spot[stx,sty];q[1].x:=stx;q[1].y:=sty;q[1].step:=0;
vis[stx,sty]:=true;
while head<tail do
begin
inc(head);
pre:=q[head];
for i:=1 to 4 do
begin
tmp.x:=pre.x+dx[i];
tmp.y:=pre.y+dy[i];
if (tmp.x>0)and(tmp.x<=n)and(tmp.y>0)and(tmp.y<=m) then
begin
ch:=map[tmp.x,tmp.y];

if (ch<>'#')and not vis[tmp.x,tmp.y] then
begin
inc(tail);
q[tail].x:=tmp.x;
q[tail].y:=tmp.y;
vis[tmp.x,tmp.y]:=true;
q[tail].pos:=spot[tmp.x,tmp.y];
q[tail].step:=q[head].step+1;
if (ch='A')or(ch='S') then refresh(tmp.x,tmp.y,stx,sty,q[tail].step);
end;
end;
end;
if tail>2500 then exit;
end;
end;
Function prim:longint;
var
i,j,k,dist,sum,min:longint;
begin
sum:=0;
lowcost[1]:=-1;
for i:=2 to p do lowcost[i]:=dis[1,i];
for i:=1 to p-1 do
begin
min:=maxlongint;
for k:=1 to p do
begin
if (lowcost[k]<>-1)and(lowcost[k]<min) then
begin
j:=k;
min:=lowcost[k];
end;
end;
sum:=sum+min;
lowcost[j]:=-1;
for k:=1 to p do if dis[j,k]<lowcost[k] then lowcost[k]:=dis[j,k];
end;
exit(sum);
end;
Begin
readln(fucks);
for fuck:=1 to fucks do
begin
init;
for i:=1 to p do getdis(link[i].x,link[i].y);
writeln(prim);
end;
End.

转载于:https://www.cnblogs.com/FreeDestiny/archive/2011/10/14/2212212.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值