大榕树——让我们共成长!
大榕树 myDrs.org
您的位置:大榕树 \ 编程       |  Logo语言   |  Pascal语言   |  信息学奥赛   |  高考保送    |  HTML版本
|  信息学奥赛>>解题报告>>《战略游戏》解题报告         本站全文搜索: 友情提示:

《战略游戏》解题报告
http://www.mydrs.org  8/11/2001  大榕树


【图论模型的建立】
  本题的数学模型在题目中已明示,我们将其用数学语言重述一遍:在图G=(V,E)中找一顶点集S,使得对任意(u,v)∈E有u∈S或v∈S,且|S|最小。很明显,这是求图的最小顶点覆盖集。
【算法分析】

  图的最小顶点覆盖是NP问题,至今还没有有效算法。而本题N的规模可达1500,显然用搜索是无法完成的。但本题的图十分特殊是一棵树。为了进一步利用数据结构的特殊性,我们不妨先手工分析一个例子。左图为一个有13个顶点的树,其中用红色圈出的顶点为找到的最小覆盖集。很明显,叶节点不可能属于覆盖集,但叶节点的父节点一定属于覆盖集,以此为基础再判断上一层次节点是否属于覆盖集。左图的节点编号从大到小正好是我们判断的顺序,该顺序恰好是树的前序遍历顺序,由此我们可得出本题的算法:

  1:procedure Min-Vertex-Cover(T);
  2:begin
  3:  按前序遍历顺序重新编排整棵树的节点编号。
  4:  for I:=1 to n do cover[I]:=0;
  5:  for I:=n Downto 2 do
  6:   if (cover[I]=0) and (cover[parent[I]]=0) then
  7:     cover[parent[I]]:=1;
  8:end;

  
  该算法是一个贪心算法。算法中用数组cover来标记选入覆盖点集的树结点,即当结点i被选入覆盖点集,则cover[i]=1,否则cover[i]=0。为了说明算法的正确性,必须证明关于树的最小顶点覆盖问题满足贪心选择性质并且具有最优子结构性质。具体的证明过程,在《若干NP完全问题的特殊情形》一文中已有详细的叙述。
  最后我们分析一下算法的复杂度,前序遍历树显然可以在O(n)时间内完成,再加上for循环显然需要O(n)的时间,从而整个算法所需的时间为O(n)。对于本题的规模,完全可以接受了。
【小结】
  本题的数学模型是一个NP问题,然而在树这样一个特殊结构下,我们充分利用题目中的已知信息,降低了题目的难度,找到了线性时间的算法。通过解这道题我认识到充分利用题目信息的重要性,一个算法越体现出题目的特征,效率也就越高,当然它的适用范围也就越狭窄,这也正是构造法解题之所以高效的原因。
【参考文献】
《若干NP完全问题的特殊情形》 《福州大学学报》99.5 王晓东

【附录】
源程序:Strategi.pas

Program exp;
Var count,m,tmp,k,j,i,n:Integer;
  Convert,Parent,Cover:Array [0..1500] Of Integer; {Convert[I]:节点I的前序遍历标号;      Parent[I]:指出节点I的父亲节点;Cover[I]:是否覆盖节点[I]}
Procedure Preorder(root:Integer); {树的前序遍历、标号过程}
Var i,j,k:Integer;
Begin
 Convert[count]:=root;Inc(count);
 For i:=1 To n Do
  If Parent[i]=root Then Preorder(i);
End;
Begin
 Assign(input,'input.txt');Reset(input);
 Assign(output,'output.txt');Rewrite(output);
 {初始化并读入数据}
 Readln(n);
 For i:=0 To n Do parent[i]:=-1;
 For i:=1 To n Do Begin
  Read(j,m);
  For k:=1 To m Do Begin
   Read(tmp);Parent[tmp]:=j;
  End;
  Readln;
 End;
 Fillchar(cover,sizeof(cover),0);
 count:=1;i:=-1;Repeat Inc(i) Until Parent[i]=-1;
 Preorder(i);count:=0;
 For i:=n Downto 2 Do {贪心算法}
  If (cover[Convert[i]]=0) and (Cover[parent[Convert[i]]]=0) Then Begin
    cover[parent[Convert[i]]]:=1;
    Inc(count);
  End;
 Writeln(count);
 Close(output);
End.


作 者:陈研
来 源:南平一中
共有2696位读者阅读过此文

  • 上篇文章:已经没有了
  • 下篇文章解题策略的谋划

  • 发送邮件
    保存页面 打印文章 HTML版本 发表评论

    □- 近期热门文章 □- 相关文章
    1. NOIP2006竞赛大纲 [8307]
    2. 七类高中生具有保送资格 [5911]
    3. NOI2006获奖选手名单 [4956]
    4. 关于举办NOIP2006模拟赛的通告 [4107]
    5. Turbo Pascal各语句运行速... [3595]
    6. Turbo王者归来新Delphi免费... [3182]
    7. IOI2006我国4名选手全部获得金... [2946]
    8. 关于APIO2007与IOI2007... [2764]
    9. noip倒计时 by 枯叶蝴蝶 [2684]
    10. 朱泽园:思想上的金牌更重要 [2169]
    《战略游戏》解题报告
    最短路径问题的求解
     

    关于本站 | 合作伙伴 | 联系方式
    大榕树 版权所有 ©1999-2006 www.myDrs.org 闽ICP备05000721号