子问题定义: 对于图中的每个结点,有两种状态,即属于最小点覆盖和不属于最小点覆盖,定义minSet[i][0]表示结点i属于点覆盖,并且以i为根的树的最小点覆盖的大小。minSet[i][1]表示点i不属于点覆盖,并且以i为根的树的最小点覆盖的大小。

递归关系:

对于minSet[i][0],i的孩子结点可以属于点覆盖,也可以不属于点覆盖,取其使以i为根的子树的点覆盖最小的情况,因此

  对于minSet[i][1],由于i不属于点覆盖,因此其所有孩子结点都必须属于点覆盖,因此

初值设定:

minSet[i][0]=1

minSet[i][1]=0

求解顺序:

从树的叶子结点开始求每个结点的最小点覆盖,自底向上,最后比较minSet[root][0]与minSet[root][1]的大小,最小者即为最终的结果。

  1. package org.xiu68.ch6.ex8;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. public class Exp6_21 {
  6.  
  7. public static void main(String[] args) {
  8. // TODO Auto-generated method stub
  9. //运行结果
  10. /*
  11. 树的最大独立集为: 4
  12. 顶点值为: 4 6 2 3
  13. 树的最小点覆盖为: 2
  14. 顶点值为: 5 1
  15. */
  16. //由结果可知 最大独立集与最小点覆盖集合互为补集
  17. ArrayList<Integer> vexs=new ArrayList<>();
  18. for(int i=1;i<=6;i++)
  19. vexs.add(i);
  20. //构造一个无向无环图
  21. int[][] edges=new int[][]{
  22. {0,1,1,0,0,0},
  23. {1,0,0,0,1,0},
  24. {1,0,0,0,0,0},
  25. {0,0,0,0,1,0},
  26. {0,1,0,1,0,1},
  27. {0,0,0,0,1,0}
  28. };
  29. MGraph<Integer> m=new MGraph<Integer>(6, 6, edges, vexs);
  30. m.maxIndependentSet();
  31. System.out.println();
  32. m.minCoverSet();
  33. }
  34. }
  35.  
  36. //邻接矩阵表示图、无向无环图
  37. class MGraph<T>{
  38. public int vexNum; //顶点数量
  39. public int edgeNum; //边数量
  40. public int[][] edges; //邻接矩阵
  41. public ArrayList<T> vexs; //顶点表
  42.  
  43. public int[][] maxDep; //最大独立集
  44. public ArrayList<Integer> set; //最大独立集顶点序号
  45.  
  46. public int[][] minCover; //最小点覆盖
  47. public ArrayList<Integer> minSet; //最小点覆盖顶点序号
  48.  
  49. public MGraph(int vexNum, int edgeNum, int[][] edges, ArrayList<T> vexs) {
  50. this.vexNum = vexNum;
  51. this.edgeNum = edgeNum;
  52. this.edges = edges;
  53. this.vexs = vexs;
  54.  
  55. maxDep=new int[vexNum][2];
  56. set=new ArrayList<>();
  57.  
  58. minCover=new int[vexNum][2];
  59. minSet=new ArrayList<>();
  60. }
  61.  
  62. //最大独立集
  63. public void maxIndependentSet(){
  64. independentSet(0, 0);
  65.  
  66. if(maxDep[0][0]>maxDep[0][1])
  67. System.out.println("树的最大独立集为: "+maxDep[0][0]);
  68. else
  69. System.out.println("树的最大独立集为: "+maxDep[0][1]);
  70.  
  71. System.out.print("顶点值为: ");
  72. for(int i=0;i<set.size();i++)
  73. System.out.print(vexs.get(set.get(i))+" ");
  74. }
  75. //求以child为根的树的最大独立集
  76. //child:当前正在处理的结点
  77. //parent:child的父结点
  78. private void independentSet(int child,int parent){
  79. maxDep[child][0]=1; //当前结点放入独立集
  80. maxDep[child][1]=0; //当前结点不放入独立集
  81.  
  82. for(int i=0;i<vexNum;i++){
  83. if(edges[child][i]==0 || i==parent) //如果顶点间不存在边或尾结点为父结点
  84. continue;
  85. independentSet(i, child);
  86.  
  87. //因为child加入了最大独立集,所以子结点不加入最大独立集
  88. //以child为根的树的最大独立集的规模为 ( 1+ child的孙子结点的最大独立集的规模 )
  89. maxDep[child][0]+=maxDep[i][1];
  90.  
  91. if(maxDep[i][0]>maxDep[i][1])
  92. maxDep[child][1]+=maxDep[i][0]; //加入子结点
  93. else
  94. maxDep[child][1]+=maxDep[i][1]; //不加入子结点
  95. }
  96.  
  97. if(maxDep[child][0]>maxDep[child][1]) //比较加入child与不加入child的独立集大小,取较大者为结果
  98. set.add(child);
  99. }
  100.  
  101. //***********************************************************
  102.  
  103. //最小点覆盖
  104. public void minCoverSet(){
  105. coverSet(0,0);
  106. if(minCover[0][0]<minCover[0][1])
  107. System.out.println("树的最小点覆盖为: "+minCover[0][0]);
  108. else
  109. System.out.println("树的最小点覆盖为: "+minCover[0][1]);
  110.  
  111. System.out.print("顶点值为: ");
  112. for(int i=0;i<minSet.size();i++){
  113. System.out.print(vexs.get(minSet.get(i))+" ");
  114. }
  115. }
  116. //求以child为根的树的最小点覆盖集合
  117. //child:当前正在处理的结点
  118. //parent:child的父结点
  119. private void coverSet(int child,int parent){
  120. minCover[child][0]=1; //child放入最小点覆盖集合
  121. minCover[child][1]=0; //child不放入最小点覆盖集合
  122.  
  123. for(int i=0;i<vexNum;i++){
  124. if(edges[child][i]==0 || i==parent) //如果顶点间不存在边或尾结点为父结点
  125. continue;
  126.  
  127. coverSet(i,child);
  128.  
  129. //如果子结点i放入集合结果更小则把i放入集合
  130. if(minCover[i][0]<minCover[i][1])
  131. minCover[child][0]+=minCover[i][0]; //子结点i放入集合
  132. else
  133. minCover[child][0]+=minCover[i][1]; //子结点i不放入集合
  134.  
  135. //若child不放入最小点覆盖集合,则其所有子结点都要放入最小点覆盖集合
  136. minCover[child][1]+=minCover[i][0];
  137.  
  138. if(minCover[child][0]<minCover[child][1]) //取最小值作为结果
  139. minSet.add(child);
  140. }
  141. }
  142. }

Ex 6_21 最小点覆盖问题_第八次作业的更多相关文章

  1. Ex 6_14 布料剪裁问题_第八次作业

    子问题定义: 定义p[i][j]为布料宽为i,高为j的最优产出,每次剪下一块布料,剩余布料最多形成三块矩阵面料.每次剪裁会有两种情况,水平切割布料,其次是将布料旋转90度后在切割布料. 递归关系: 初 ...

  2. Ex 6_5棋子放置问题_第八次作业

    题目貌似有问题 (b) 子问题定义: 设maxValue[i][j]为棋盘的前i行中最后一行为i时第i行按照第j种放置方式放置时得到的最大覆盖值,comp[i][j]为第i种放置方式与第j种放置方式是 ...

  3. ACM/ICPC 之 机器调度-匈牙利算法解最小点覆盖集(DFS)(POJ1325)

    //匈牙利算法-DFS //求最小点覆盖集 == 求最大匹配 //Time:0Ms Memory:208K #include<iostream> #include<cstring&g ...

  4. 【POJ 3041】Asteroids (最小点覆盖)

    每次选择清除一行或者一列上的小行星.最少选择几次. 将行和列抽象成点,第i行为节点i+n,第j列为节点j,每个行星则是一条边,连接了所在的行列. 于是问题转化成最小点覆盖.二分图的最小点覆盖==最大匹 ...

  5. POJ 2226 最小点覆盖(经典建图)

    Muddy Fields Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8881   Accepted: 3300 Desc ...

  6. nyoj 237 游戏高手的烦恼 二分匹配--最小点覆盖

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=237 二分匹配--最小点覆盖模板题 Tips:用邻接矩阵超时,用数组模拟邻接表WA,暂时只 ...

  7. [USACO2005][POJ2226]Muddy Fields(二分图最小点覆盖)

    题目:http://poj.org/problem?id=2226 题意:给你一个字符矩阵,每个位置只能有"*"或者“.",连续的横着或者竖的“*"可以用一块木 ...

  8. POJ3041Asteroids(最小点覆盖+有点小抽象)

    Asteroids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18289   Accepted: 9968 Descri ...

  9. hdu 1054 最小点覆盖

    Sample Input 4 0:(1) 1 1:(2) 2 3 2:(0) 3:(0) 5 3:(3) 1 4 2 1:(1) 0 2:(0) 0:(0) 4:(0)   Sample Output ...

随机推荐

  1. 【POJ1015】Jury compromise 多个费用的背包

    这是一道比较综合的动态规划问题. 首先,根据题目中的从N个人中选出M个人,并且要使得某个目标函数最优,可以想到是背包问题,且因为要取出M个人,人数也应该作为背包体积的一个维度. 其次,要求输出路径,因 ...

  2. 提高磁盘访问性能 - NtfsDisableLastAccessUpdate

    这个技巧可以提高磁盘访问性能,不过仅适用于NTFS文件系统. 我们知道,当在磁盘管理应用程序中列出目录结构时──效果类似“资源管理器”.“文件管理 器”(Windows NT  3.xx/4.0下的称 ...

  3. Class对象、反射机制、获取Constructor构造方法

    1.Class对象的三种创建方法(Class首字母大写) public class Demo { public static void main(String[] args){ Object obj= ...

  4. springboot的跨域

    https://www.cnblogs.com/520playboy/p/7306008.html 1.对于前后端分离的项目来说,如果前端项目与后端项目部署在两个不同的域下,那么势必会引起跨域问题的出 ...

  5. kubernetes控制器之DaemonSet

    转载于https://blog.csdn.net/bbwangj/article/details/82867472 什么是 DaemonSet? DaemonSet 确保全部(或者一些)Node 上运 ...

  6. java连接mysql的过程

    今天突然心血来潮,想要用java连接mysql,记得以前是在vs2010的环境下用C#连接sql sever,其实他们的方法都差不多. 现在就可以简单的介绍下java如何连接mysql 第一步,设计m ...

  7. mysql 之各种 join 之间的关系

    一.了解一下 mysql 中所拥有的各种 join left join(左联接):返回包括左表中的所有记录和右表中联结字段相等的记录  right join(右联接):返回包括右表中的所有记录和左表中 ...

  8. Java_JDBC一般写法

    JDBC是Java DataBase Connectivity,Java程序访问数据库的标准接口. 如果是maven工程先加入依赖的jar包: <dependency> <group ...

  9. Java跨平台(系统)的主要原理

    Java是可以在系统运行的,主要是Java在执行的时候先通过Java虚拟机JVM,对应不同的操作系统,JVM会采用对应的翻译机制.

  10. excel自动化翻译2

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...