NOIP2003 传染病控制
一道答题解法一定细节解法并不怎么确定的题目,总体上就是搜索了。在每层当前可被感染的人中,只能选一个人,就先DFS建树,统计每一层的人,保存在一个表里,再进行搜索,一个人被控制后,就用递归把他的儿子全部赋值成不能染病,并在可染病人数中减去该子树大小,取最小值即可。
统计官方上都说要剪枝,但是我的程序最大点0.2S。
View Code
1 program noip2003t4(input,output); 2 type 3 node=^link; 4 link=record 5 goal:longint; 6 next:node; 7 end; 8 var 9 l,tree:array[0..401] of node; 10 nodes:array[0..400,0..400] of longint; 11 answer:longint; 12 n,p,sum,maxdepth:longint; 13 can,v:array[0..400] of boolean; 14 procedure add(xx,yy:longint); 15 var 16 tt:node; 17 begin 18 new(tt); 19 tt^.next:=l[xx]; 20 tt^.goal:=yy; 21 l[xx]:=tt; 22 end;{ add } 23 procedure add_tree(xx,yy:longint); 24 var 25 tt:node; 26 begin 27 new(tt); 28 tt^.goal:=yy; 29 tt^.next:=tree[xx]; 30 tree[xx]:=tt; 31 end;{ add_tree } 32 procedure init; 33 var 34 i,xx,yy:longint; 35 begin 36 readln(n,p); 37 for i:=1 to n do 38 begin 39 l[i]:=nil; 40 tree[i]:=nil; 41 end; 42 for i:=1 to p do 43 begin 44 read(xx,yy); 45 add(xx,yy); 46 add(yy,xx); 47 end; 48 fillchar(nodes,sizeof(nodes),0); 49 end;{ init } 50 procedure build(now:longint); 51 var 52 t:node; 53 begin 54 v[now]:=true; 55 t:=l[now]; 56 while t<>nil do 57 begin 58 if not v[t^.goal] then 59 begin 60 add_tree(now,t^.goal); 61 build(t^.goal); 62 end; 63 t:=t^.next; 64 end; 65 end;{ build } 66 procedure calc(now,depth:longint); 67 var 68 t:node; 69 begin 70 if depth>maxdepth then 71 maxdepth:=depth; 72 inc(nodes[depth,0]); 73 nodes[depth,nodes[depth,0]]:=now; 74 t:=tree[now]; 75 while t<>nil do 76 begin 77 calc(t^.goal,depth+1); 78 t:=t^.next; 79 end; 80 end;{ calc } 81 function change(now:longint;flag:boolean):longint; 82 var 83 t:node; 84 begin 85 change:=1; 86 can[now]:=flag; 87 t:=tree[now]; 88 while t<>nil do 89 begin 90 change:=change+change(t^.goal,flag); 91 t:=t^.next; 92 end; 93 end;{ change } 94 function check(now:longint):boolean; 95 var 96 i:longint; 97 begin 98 for i:=1 to nodes[now,0] do 99 if can[nodes[now,i]] then 100 exit(true); 101 exit(false); 102 end;{ check } 103 procedure dfs(depth:longint); 104 var 105 i:longint; 106 begin 107 if depth=maxdepth+1 then 108 begin 109 if sum<answer then 110 answer:=sum; 111 exit; 112 end; 113 for i:=1 to nodes[depth,0] do 114 if can[nodes[depth,i]] then 115 begin 116 dec(sum,change(nodes[depth,i],false)); 117 if not check(depth+1) then 118 begin 119 if sum<answer then 120 answer:=sum; 121 end 122 else 123 dfs(depth+1); 124 inc(sum,change(nodes[depth,i],true)); 125 end; 126 end;{ dfs } 127 procedure main; 128 begin 129 maxdepth:=0; 130 fillchar(can,sizeof(can),true); 131 fillchar(v,sizeof(v),false); 132 answer:=maxlongint; 133 build(1); 134 calc(1,1); 135 sum:=n; 136 dfs(2); 137 writeln(answer); 138 end;{ main } 139 begin 140 assign(input,'Epidemic.in');reset(input); 141 assign(output,'Epidemic.out');rewrite(output); 142 init; 143 main; 144 close(input); 145 close(output); 146 end.