网站大量收购独家精品文档,联系QQ:2885784924

《食物链》解题报告.docVIP

  1. 1、本文档共7页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
《食物链》解题报告

《食物链》解题报告 广东北江中学 方奇 问题描述 见Noi2001全国信息学奥赛第一试第一题 问题抽象 如何判断两个动物之间的关系,是解决本题的关键。对应于图论模型,将每个动物看成一个点,并将在输入数据中出现的有直接联系的每对动物之间连一条边。那么,任两个动物之间存在联系,当且仅当对应的两个点处在同一连同分支中。若将互相有联系的动物归于一个集合,那么本题实际上是一个典型的并查集问题。 问题分析 并查集的实现,利用树这种数据结构,无论时空上都是最优的。 结合本题,描述如下: 一棵树对应于一群相互间确定了关系的动物,树的一个结点对应于一个动物。Father[I]记录了结点I的父亲,当I为根结点时,有Father[I]=0。Kind[I]记录了结点I与父亲的相对关系:1表示I被Father[I]吃;2表示I吃Father[I];0表示I与Father[I]是同类。当I为根结点时,有Kind[I]=0。 算法开始时,Father[I]=0,Kind[I]=0,表示先建立n棵不同的树。 容易设计出算法的流程 简单 判断后 Y N Y N 下面来看看关键步骤如何实现。 利用Father,不断上溯,分别找出x、y所属树的根结点Rootx、Rooty。则x、y处在同一棵树中,当且仅当Rootx=Rooty。例如: Rootx=x; While father[rootx]0 do rootx:=father[rootx]; 在中添加运算,得到x、y分别与根的关系d1、d2 Rootx:=x;d1:=0; While father[rootx]0 do Begin D1:=(d1+kind[rootx]) mod 3; Rootx:=father[rootx]; End; 从而得到x、y之间的关系d3=(d1+3-d2) mod 3 与相同,先求出d1、d2,在结合x与y之间的关系d,确定出rootx、rooty之间的关系d4=(d1+(d-1)-d2+3) mod 3。合并时只需修改Father[rooty]=rootx、Kind[rooty]=d4即可。 可以看出、本身的耗时都为O(1),但它们都要借助与的结果。当树退化成一条链时,每次耗时将达到O(n)。于是有必要进行改进。 改进一 设num[root]记录以root为根的树的结点数(不含根),每次合并时总将“小树”合并到“大树”中。随着小树T1合并到大树T2中,T1的每个结点深度增加1,且合并后的T2的结点数至少是T1的结点数的2倍。于是,并查集中的每个结点至多被移动O(logN)次,从而每个结点所在树的高度不会超过O(logN)。所以每次只需O(logN)时间。 改进二 采用路径压缩技术。即在每次执行的过程中,记录下上溯的路径,将路上所有结点的父亲(Father) 经过上述改进后,算法的时间复杂度大大减少,基本上可以认为是O(N+K)。 程序注释 Program Eat; var father,kind,num,l1,l2:array[1..50000] of longint; i,j,k,n,m,x,y,z,k1,k2,t1,t2,tot:longint; root1,root2:longint; f1,f2:text; procedure init; {初始化文件} begin assign(f1,eat.in); reset(f1); assign(f2,eat.out); rewrite(f2); readln(f1,n,m); end; procedure main; {主过程} procedure Findroot; {上溯出结点的根} begin t1:=0;root1:=x;k1:=0; while root10 do begin inc(t1); l1[t1]:=root1; k1:=(k1+kind[root1]) mod 3; root1:=father[root1]; end; root1:=l1[t1]; {root1为x的根,k1为x与根的关系} t2:=0;root2:=y;k2:=0; while root20 do begin inc(t2); l2[t2]:=root2

文档评论(0)

qwd513620855 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档