- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
传染病控制解题报告
传染病控制解题报告
题意简述:
给定一棵树,其根节点1是已经被感染的患者。在一个疾病传播周期内,只能切断树的一条边,然后所有被感染的节点的孩子节点也会被感染。要求一个最佳的切断边的方案,使被感染的节点数最小。
解法分析:
将被感染节点中深度最大的节点集合称之为最新传染源,设为。当经过个疾病传播周期,传染病传播的最新传染源的深度是一定的,即为(根节点1的深度为0)。因此可以得到以下动态规划算法:设表示经过X个疾病传播周期且最新传染源集合为被感染节点的最小值,那么由可以推得,其中表示集合中所有的孩子节点,是被切断边的一个深度较大的节点。似乎问题已经得到了很好的解决,但是考察一下算法的空间复杂度,达到了,这是完全不可能实现的。
鉴于空间上的问题,我们只好放弃动态规划。尝试先从简单的角度思考问题:搜索的效果会怎么样呢?分析一下问题的状态空间:题目给定的是一棵树。把题目中的树称为原树,搜索树的层数就是原树的深度,而搜索树的分叉数多少与原树的宽度有关。综合起来看,原树深度较大,宽度会较小;而原树宽度较大,深度又会较小,所以搜索树的规模没有想象中那么大。
证明了搜索是“可能”出解的,剩下的就是怎么搜的问题:在个传播周期内疾病传播达到的深度是一定的,为。如果在深度小于的位置切断边,由于已经通过它进行了传播,切断是没有意义的;如果在深度大于的位置切断边,效果肯定不如把它的祖先切断。因此最优的切断方法必须是切断与相连的边中的一条。这样搜索已经可以通过大部分数据,但是对于极限大数据还是无法出解,需要优化。
优化一:初看这道题目的时候会想到贪心。也就是每次选节点数目最大的子树删除,虽然很容易找到反例,但是我们仍然可以认为选节点数目最大的子树删除更“可能”得到最优解,因此可以按照子树节点数目从大到小删除。
优化二:最优性剪枝。设当前已经搜到了第层,有个节点已被感染,那么如果有
即可剪枝。这是因为在一个疾病传播周期内,最多只能切断树的一条边,所以在下一周期至少还有个新感染的节点。
优化三:搜索最后一两层时,由于子树的结构都相同,随便选择一个删除就可以退出了。
加入这三个优化后,程序的效率大大提高。最大官方数据在0.2s内解出。
参考程序:
{$R-,Q-,S-,I-}
{$M 65521,0,655360}
{Author:Zhou Gelin}
{Date:2005.1.11}
{QQ:379688236}
{MSN:zhougelin@}
{Test Report}
{P4 1.7G}
{Windows Xp SP1}
{Turbo Pascal 7.0}
{
EPIDEMIC.in1 = 10.0 (0.06s)
EPIDEMIC.in2 = 10.0 (0.08s)
EPIDEMIC.in3 = 10.0 (0.05s)
EPIDEMIC.in4 = 10.0 (0.03s)
EPIDEMIC.in5 = 10.0 (0.03s)
EPIDEMIC.in6 = 10.0 (0.03s)
EPIDEMIC.in7 = 10.0 (0.06s)
EPIDEMIC.in8 = 10.0 (0.03s)
EPIDEMIC.in9 = 10.0 (0.20s)
EPIDEMIC.in0 = 10.0 (0.11s)
}
program epidemic;
const inputfilename=epidemic.in;
outputfilename=epidemic.out;
maxn=300;
type pnode=^node;
node=record
data:integer;
next:pnode;
end;
list=array[1..maxn]of integer;
var n,p,maxdep,ans:integer;
g:array[1..maxn]of pnode;
father:array[1..maxn]of integer;
dep:array[1..maxn]of integer;
sum:array[1..maxn]of integer;
deg:array[1..maxn]of integer;
son:array[1..maxn]of ^list;
a:array[1..maxn]of boolean;
procedure insert(a,b:integer);
var q:pnode;
begin
new(q);
q^.data:=b;
q^.next:=g[a];
g[a]:=q;
end;
procedure read_data
文档评论(0)