题目: | 传染病控制 | |
来源: | Noip 2003T4 | |
题目大意: | 在一棵树中,每层任意砍掉一条边,使包含根结点的树的结点数最少。 | |
数据范围: | 1≤n≤300 | |
样例: | 7 6 1 2 1 3 2 4 2 5 3 6 3 7 | 3 |
做题思路: | 本以为是树型dp,结果写好多叉转二叉的树后发现不对,真耽误时间啊。 正解是搜索。。。而且是无向图。。。 | |
知识点: | 搜索 |
var
a:array[0..400,0..400]of longint;
time:array[0..400]of longint;
n,i,x,y,ans,sum,m:longint;
procedure build(k:longint);{<构造,减去自己和自己的边>}
var
i,j,t:longint;
begin
fori:=1 to a[k,0] do
begin
t:=a[k,i];
forj:=1 to a[t,0] do
ifa[t,j]=k then break;
a[t,j]:=a[t,a[t,0]];
dec(a[t,0]);
build(t);
end;
end;
procedure dfs(k:longint);
var
i,j:longint;
b:boolean;
begin
b:=false;
ifsum>ans then exit; {<最优化剪枝>}
fori:=1 to n do
iftime[i]=k then{<处理下一层的条件是传染到了这一层>}
forj:=1 to a[i,0] do
begin
inc(sum);
time[a[i,j]]:=k+1;
b:=true;
end;
dec(sum);
fori:=1 to n do{<选择一个边向下处理>}
iftime[i]=k+1 then
begin
time[i]:=0;
dfs(k+1);
time[i]:=k+1;
end;
inc(sum);
fori:=1 to n do{<回溯>}
iftime[i]=k+1 then
begin
time[i]:=0;
dec(sum);
end;
if(not b)and(sum<ans) then ans:=sum;
end;
begin
assign(input,'Epidemic.in');reset(input);
assign(output,'Epidemic.out');rewrite(output);
readln(n,m);
fori:=1 to m do
begin
readln(x,y);
inc(a[x,0]); {<因为题目没说,所以指不定谁传染谁>}
a[x,a[x,0]]:=y;
inc(a[y,0]);
a[y,a[y,0]]:=x;
end;
build(1);
sum:=1;ans:=maxlongint;
time[1]:=1;
dfs(1);
writeln(ans);
close(input);close(output);
end.
题目来源:
http://yt.tyvj.cn:8080/Problem_Show.asp?id=1041