题目:https://jzoj.net/junior/#main/problemset/11?seed=0.9450941455370403
这道题是一道单纯的dfs类型题目,关键是如何判断组成图形。首先必须有的标记就是当前这条边有没有被经过,这是非常容易想到的,还有一个标记就是如何判断当前选择的边组成的是一个不规则图形,也就是不能形成一个符合要求的区域。
举个栗子:
加上这两个bz再加上一个剪枝优化,时间0ms妥妥的。注明一下:f数组是判断有没有重复过点,w数组是判断有没有重复边 .bz则是输入的边。
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>var
f:array[1..100,1..2] of boolean;
bz:array[1..100,0..100,1..2] of longint;
len:array[1..100] of longint;
w:array[1..100] of boolean;
n,i,j,s,t,m1,m2,min:longint;
procedure dfs(k,sum,tot:Longint);
var
i,p:Longint;
begin
if sum-len[j]>=min then exit;
if (tot>2) and (k=j) then
begin
if sum-len[j]<min then min:=sum-len[j];
exit;
end;
for i:=1 to bz[k,0,1] do
if (f[k,1]) and w[bz[k,i,1]] then
begin
w[bz[k,i,1]]:=false;
for p:=1 to bz[bz[k,i,1],0,1]+1 do
if bz[bz[k,i,1],p,1]=k then break;
if p<>bz[bz[k,i,1],0,1]+1 then f[bz[k,i,1],1]:=false else f[bz[k,i,1],2]:=false;
dfs(bz[k,i,1],sum+len[bz[k,i,1]],tot+1);
if p<>bz[bz[k,i,1],0,1]+1 then f[bz[k,i,1],1]:=true else f[bz[k,i,1],2]:=true;
w[bz[k,i,1]]:=true;
end;
for i:=1 to bz[k,0,2] do
if (f[k,2]) and w[bz[k,i,2]] then
begin
w[bz[k,i,2]]:=false;
for p:=1 to bz[bz[k,i,2],0,1]+1 do
if bz[bz[k,i,2],p,1]=k then break;
if p<>bz[bz[k,i,2],0,1]+1 then f[bz[k,i,2],1]:=false else f[bz[k,i,2],2]:=false;
dfs(bz[k,i,2],sum+len[bz[k,i,2]],tot+1);
if p<>bz[bz[k,i,2],0,1]+1 then f[bz[k,i,2],1]:=true else f[bz[k,i,2],2]:=true;
w[bz[k,i,2]]:=true;
end;
end;
begin
readln(n);
for i:=1 to n do
begin
readln(s,len[s],m1,m2);
for j:=1 to m1 do
begin
read(t);
inc(bz[s,0,1]);
bz[s,bz[s,0,1],1]:=t;
end;
for j:=1 to m2 do
begin
read(t);
inc(bz[s,0,2]);
bz[s,bz[s,0,2],2]:=t;
end;
end;
min:=maxlongint;
for j:=1 to n do
begin
fillchar(f,sizeof(f),true);
fillchar(w,sizeof(w),true);
dfs(j,len[j],1);
end;
writeln(min);
end.</strong></span>