树的最小重量顶点覆盖

时间:2014-12-17 00:54:58

标签: algorithm graph tree dynamic-programming vertex-cover

有一个existing question处理树,其中顶点的权重是它的度数,但我对顶点可以有任意权重的情况感兴趣。

这不是家庭作业,但算法设计手册中的一个问题,我正在阅读;答案集给出了解决方案

  1. 执行DFS,在每一步更新Score [v] [include],其中v是顶点,include包含true或false;
  2. 如果v是叶子,则设置Score [v] [false] = 0,Score [v] [true] = w v ,其中w v 是顶点重量v。
  3. 在DFS期间,当从节点v的最后一个孩子向上移动时,更新Score [v] [include]: 得分[v] [false] =儿童中c的总和(v)得分[c] [真]和得分[v] [真] = w v +儿童c总和(v) )min(分数[c] [true];分数[c] [false])
  4. 通过回溯分数提取实际封面。
  5. 但是,我实际上无法将其转换为工作的内容。 (回应评论:我到目前为止所尝试的是绘制一些带有权重的小图并在纸上运行算法,直到第四步,“提取实际封面”部分不透明。)

    回答阿里的回答:假设我有这个图,其中顶点由A等给出,而后面是权重:

    A(9)---B(3)---C(2) \ \ E(1) D(4)

    正确答案显然是{B,E}

    通过这个算法,我们设置如下值:

    • score[D][false] = 0; score[D][true] = 4
    • score[C][false] = 0; score[C][true] = 2
    • score[B][false] = 6; score[B][true] = 3
    • score[E][false] = 0; score[E][true] = 1
    • score[A][false] = 4; score[A][true] = 12

    好的,我的问题基本上是,现在是什么?做一件简单的事情并遍历score向量并决定本地最便宜的东西不起作用;你最终只包括B。基于父级和交替的决定也不起作用:考虑E的权重为1000的情况;现在正确的答案是{A,B},它们是相邻的。也许它不应该让人感到困惑,但坦率地说,我很困惑。

2 个答案:

答案 0 :(得分:1)

回溯是前面步骤中所做的。第4步没有特殊含义,它也可以说“找出如何处理Score”。

树的覆盖顶点允许包含交替的顶点和相邻的顶点。不允许排除两个相邻的顶点,因为它必须包含所有边。

答案以递归计算得分的方式给出。不包含顶点的成本就是包含其子级的成本。但是,包含一个顶点的成本要便宜得多,因为包含两个子元素都是允许的,所以包含或不包含它们的成本也较低。

正如您的解决方案所建议的那样,可以使用DFS一次完成一次订购。诀窍是,如果Score指出必须包含一个顶点,则包括一个顶点,如果必须排除它,则包括其子对象,否则我们将排除两个相邻的顶点。

这是一些伪代码:

navVC.viewControllers = [vc]

答案 1 :(得分:0)

它实际上并不意味着任何令人困惑的东西,它只是Dynamic Programming,你似乎几乎理解所有的算法。如果我想让它更清楚,我不得不说:

  1. 首先在你的图表上预先形成DFS并找到叶子。
  2. 为每个叶子分配值,如算法所示。
  3. 现在从叶子开始,并通过该公式为每个叶子父级分配值。
  4. 开始为已经拥有值的节点的父节点分配值,直到到达图形的根目录。
  5. 就是这样,通过回溯你的算法,它意味着你为每个节点赋予其子节点已经有值的值。如上所述,这种解决问题称为动态编程。

    修改仅用于解释您对问题的更改。正如你有下面的图表,答案显然是B,E但是你虽然这个算法只给你B但你不对,这个算法给你B和E.

    A(9)---B(3)---C(2) \ \ E(1) D(4)

    score[D][false] = 0; score[D][true] = 4
    score[C][false] = 0; score[C][true] = 2
    score[B][false] = 6 this means we use C and D; score[B][true] = 3 this means we use B
    score[E][false] = 0; score[E][true] = 1
    score[A][false] = 4 This means we use B and E; score[A][true] = 12 this means we use B and A.
    

    你选择4所以你必须使用B和E.如果它只是B你的答案是3.但正如你发现它正确你的答案是4 = 3 + 1 = B + E.

    当E = 1000

    A(9)---B(3)---C(2) \ \ E(1000) D(4)

    答案是B和A 100%是正确的,因为你不想选择相邻的节点而使用E是错误的。使用此算法,您会发现答案是A和B,只需检查您是否也可以找到答案。假设这包括:

    C D A = 15
    C D E = 1006
    A B = 12
    

    虽然前两个答案没有相邻节点,但它们比具有相邻节点的最后一个答案大。因此最好使用A和B作为封面。