题目地址:http://codevs.cn/problem/1002/
分析:
代码:
const maxr=52;maxe=3010;
type
tnode=record
a,b,c:integer;
end;
tmap=array[0.. maxr+1,0.. maxr+1] of integer;
var
r,c:integer;
map:tmap;
n,e:integer;
erc:array[1.. maxe] of tnode;
f:array[1 .. maxe] of integer;
resulta,resultb:integer;
procedure getinfo;
var i,j:integer;
ch:char;
begin
readln(r, c);
for i:=1 to r do
begin
for j:=1 to c do
begin
read(ch);
if ch='.' then map[i,j]:=0
else map[i,j]:=-1;
end;
readln;
end;
end;
procedure getvex(x,y:integer);
var i,h,t:integer;
dx,dy,nx,ny:integer;
q:array[1 .. maxe, 1 .. 2] of integer;
begin
h:=0;
t:=1;
q[1,1]:=x;
q[1,2]:=y;
inc(n); //n是建筑物的总数
map[x,y]:=n; //map[x,y]是什么含义?
repeat
inc(h);
for dx:=-1 to 1 do
for dy:=-1 to 1 do
if (dx<>0) or (dy<>0) then
begin
nx:=q[h,1]+dx;
ny:=q[h,2]+dy;
if map[nx,ny]<>-1 then continue;
map[nx,ny]:=n;
inc(t);
q[t,1]:=nx;
q[t,2]:=ny;
end;
until h=t;
end;
procedure inserterc(a,b,c:integer);
begin
if (a=0) or (b=0) or (a=b) then exit;
inc(e);
erc[e].a:=a;
erc[e].b:=b;
erc[e].c:=c;
end;
procedure init;
var
last,i,j:integer;
point:array[0.. maxr, 0 .. maxr] of integer;
begin
n:=0;
for i:= 1 to r do
for j:= 1 to c do
if map[i, j]=-1 then getvex(i, j);
fillchar(point, sizeof(point), 0);
for i:= 1 to r do
for j:= 1 to c do
if map[i, j]<>0 then
begin
point[i,j]:=map[i,j];
point[i-1,j]:=map[i,j];
point[i, j-1]:=map[i,j];
point[i-1,j-1] := map[i, j];
end;
for i := 0 to r do
begin
last := -1;
for j := 0 to c do
if point[i, j] <> 0 then begin
if last <> -1 then
inserterc(point[i, last], point[i, j], j - last);
last := j;
end;
end;
for j := 0 to c do
begin
last := -1;
for i := 0 to r do
if point[i, j] <> 0 then
begin
if last <> -1 then
inserterc(point[last, j], point[i, j], i - last);
last := i;
end;
end;
for i := 1 to n do f[i] := -1;
end;
procedure sift(s, t : integer);
var
i, j : integer;
tmp : tnode;
begin
i := s; j := i + i; tmp := erc[i];
while j <= t do
begin
if (j < t) and (erc[j + 1].c > erc[j].c) then inc(j);
if tmp.c >= erc[j].c then break;
erc[i] := erc[j];
i := j; j := i + i;
end;
erc[i] := tmp;
end;
procedure sort;
var
swap:tnode;
i:integer;
begin
for i:=e shr 1 downto 1 do
sift(i, e);
for i:=e downto 2 do
begin
swap:=erc[i];
erc[i]:=erc[1];
erc[1]:=swap;
sift(1,i-1);
end;
end;
function root(v : integer) : integer;
var
tmp,t:integer;
begin
t:=v;
while f[t]>0 do t:=f[t];
root:=t;
while f[v]>0 do
begin
tmp:=f[v];
f[v]:=t;
v:=tmp;
end;
end;
procedure merge(x, y : integer);
var
swap:integer;
begin
if -f[x]<-f[y] then
begin
swap:=x;
x:=y;
y:=swap;
end;
f[x]:=f[x]+f[y];
f[y]:=x;
end;
procedure main;
var
a,b,i:integer;
begin
resulta:=0;
resultb:=0;
for i:= 1 to e do
begin
a:=root(erc[i].a);
b:=root(erc[i].b);
if a<>b then
begin
inc(resulta); inc(resultb, erc[i].c);
merge(a, b)
end;
end;
end;
procedure print;
begin
writeln(n);
writeln(resulta, ' ', resultb);
end;
begin
getinfo;
init;
sort;
main;
print;
end.