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.
posted @ 2012-05-10 10:43  Codinginging  阅读(677)  评论(0编辑  收藏  举报