【问题描述】

给定一个无回路的无向图(即树),设计一个动态规划算法,求出该图的最大独立集,并输出该集合中的各个顶点值。

  1. package org.xiu68.exp.exp7;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. public class Exp7_1 {
  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. //邻接矩阵表示图、无向无环图
  38. class MGraph<T>{
  39. public int vexNum; //顶点数量
  40. public int edgeNum; //边数量
  41. public int[][] edges; //邻接矩阵
  42. public ArrayList<T> vexs; //顶点表
  43.  
  44. public int[][] maxDep; //最大独立集
  45. public ArrayList<Integer> set; //最大独立集顶点序号
  46.  
  47. public int[][] minCover; //最小点覆盖
  48. public ArrayList<Integer> minSet; //最小点覆盖顶点序号
  49.  
  50. public MGraph(int vexNum, int edgeNum, int[][] edges, ArrayList<T> vexs) {
  51. this.vexNum = vexNum;
  52. this.edgeNum = edgeNum;
  53. this.edges = edges;
  54. this.vexs = vexs;
  55.  
  56. maxDep=new int[vexNum][2];
  57. set=new ArrayList<>();
  58.  
  59. minCover=new int[vexNum][2];
  60. minSet=new ArrayList<>();
  61. }
  62.  
  63. //最大独立集
  64. public void maxIndependentSet(){
  65. independentSet(0, 0);
  66.  
  67. if(maxDep[0][0]>maxDep[0][1])
  68. System.out.println("树的最大独立集为: "+maxDep[0][0]);
  69. else
  70. System.out.println("树的最大独立集为: "+maxDep[0][1]);
  71.  
  72. System.out.print("顶点值为: ");
  73. for(int i=0;i<set.size();i++)
  74. System.out.print(vexs.get(set.get(i))+" ");
  75. }
  76. //求以child为根的树的最大独立集
  77. //child:当前正在处理的结点
  78. //parent:child的父结点
  79. private void independentSet(int child,int parent){
  80. maxDep[child][0]=1; //当前结点放入独立集
  81. maxDep[child][1]=0; //当前结点不放入独立集
  82.  
  83. for(int i=0;i<vexNum;i++){
  84. if(edges[child][i]==0 || i==parent) //如果顶点间不存在边或尾结点为父结点
  85. continue;
  86. independentSet(i, child);
  87.  
  88. //因为child加入了最大独立集,所以子结点不加入最大独立集
  89. //以child为根的树的最大独立集的规模为 ( 1+ child的孙子结点的最大独立集的规模 )
  90. maxDep[child][0]+=maxDep[i][1];
  91.  
  92. if(maxDep[i][0]>maxDep[i][1])
  93. maxDep[child][1]+=maxDep[i][0]; //加入子结点
  94. else
  95. maxDep[child][1]+=maxDep[i][1]; //不加入子结点
  96. }
  97.  
  98. if(maxDep[child][0]>maxDep[child][1]) //比较加入child与不加入child的独立集大小,取较大者为结果
  99. set.add(child);
  100. }
  101.  
  102. //***********************************************************
  103.  
  104. //最小点覆盖
  105. public void minCoverSet(){
  106. coverSet(0,0);
  107. if(minCover[0][0]<minCover[0][1])
  108. System.out.println("树的最小点覆盖为: "+minCover[0][0]);
  109. else
  110. System.out.println("树的最小点覆盖为: "+minCover[0][1]);
  111.  
  112. System.out.print("顶点值为: ");
  113. for(int i=0;i<minSet.size();i++){
  114. System.out.print(vexs.get(minSet.get(i))+" ");
  115. }
  116. }
  117. //求以child为根的树的最小点覆盖集合
  118. //child:当前正在处理的结点
  119. //parent:child的父结点
  120. private void coverSet(int child,int parent){
  121. minCover[child][0]=1; //child放入最小点覆盖集合
  122. minCover[child][1]=0; //child不放入最小点覆盖集合
  123.  
  124. for(int i=0;i<vexNum;i++){
  125. if(edges[child][i]==0 || i==parent) //如果顶点间不存在边或尾结点为父结点
  126. continue;
  127.  
  128. coverSet(i,child);
  129.  
  130. //如果子结点i放入集合结果更小则把i放入集合
  131. if(minCover[i][0]<minCover[i][1])
  132. minCover[child][0]+=minCover[i][0]; //子结点i放入集合
  133. else
  134. minCover[child][0]+=minCover[i][1]; //子结点i不放入集合
  135.  
  136. //若child不放入最小点覆盖集合,则其所有子结点都要放入最小点覆盖集合
  137. minCover[child][1]+=minCover[i][0];
  138.  
  139. if(minCover[child][0]<minCover[child][1]) //取最小值作为结果
  140. minSet.add(child);
  141. }
  142. }
  143. }

Expm 7_1树中的最大独立集问题的更多相关文章

  1. UVA - 1220 Party at Hali-Bula 树的最大独立集

    题意:  给定n个人,存在上下级关系,每个人只有一个上级,求最大独立集.并判断最大独立集是否唯一 思路:d[i][0]表示以i为根的子树中,不选择第i个节点的最大独立集,f[i][0]表示以i为根的子 ...

  2. UVa 1220 Hali-Bula的晚会(树的最大独立集)

    https://vjudge.net/problem/UVA-1220 题意: 公司里有n个人形成一个树状结构,即除了老板以外每个员工都有唯一的直属上司.要求选尽量多的人,但不能同时选择一个人和他的直 ...

  3. [LeetCode] Delete Node in a BST 删除二叉搜索树中的节点

    Given a root node reference of a BST and a key, delete the node with the given key in the BST. Retur ...

  4. [LeetCode] Inorder Successor in BST 二叉搜索树中的中序后继节点

    Given a binary search tree and a node in it, find the in-order successor of that node in the BST. No ...

  5. [LeetCode] Kth Smallest Element in a BST 二叉搜索树中的第K小的元素

    Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Not ...

  6. eclipse 中过滤空包,目录树中不显示。

    1.导入maven工程,目录树中显示空包. 在Package Explorer的左上角,有个倒三角形,点开,有Fileters 选项,点开, Filters 中,勾上 Empty packages.即 ...

  7. poj 3692 Kindergarten (最大独立集)

    Kindergarten Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4903   Accepted: 2387 Desc ...

  8. 【BZOJ-4316】小C的独立集 仙人掌DP + 最大独立集

    4316: 小C的独立集 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 57  Solved: 41[Submit][Status][Discuss] ...

  9. loj 1201(最大独立集)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26913 思路:水题一枚,就是求最大独立集.最大独立集=顶点数-最大 ...

随机推荐

  1. 洛谷P4145 上帝造题的⑦minutes ②

    又是线段树. 区间开平方求和,套路题. 如果开到了1就不用再开下去了,否则直接到底. 记得 l > r 时交换 l r #include <cstdio> #include < ...

  2. A1047. Student List for Course

    Zhejiang University has 40000 students and provides 2500 courses. Now given the registered course li ...

  3. poj 2785(折半枚举+二分搜索)

    传送门:Problem 2785 题意: 给定 n 行数,每行都有 4 个数A,B,C,D. 要从每列中各抽取出一个数,问使四个数的和为0的所有方案数. 相同数字不同位置当作不同数字对待. 题解: 如 ...

  4. 单机安装ELK

    . 简介 1.1 介绍 ELK是三个开源工具组成,简单解释如下: Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格 ...

  5. JAVA实现SFTP实例

    最近写的一个JAVA实现SFTP的实例: /* * Created on 2009-9-14 * Copyright 2009 by www.xfok.net. All Rights Reserved ...

  6. Python基础【day03】:集合进阶(四)

    本节内容 1.关系测试(特殊符号) 1.交集2.并集3.差集4.对称差集5.是否是子集6.是否是父集 2.基本操作 1.add2.update3.remove VS pop vs discard4.l ...

  7. JavaSE学习总结(二)——Java语言基础

    一.Java程序预览 Java的语法与C非常类似,这里先使用几个非常简单的程序以点带面来区分C语Java的区分再细讲每个知识点.该文仅针对有编程基础的朋友参考. 1.1.Hello World 创建j ...

  8. mysql -- 索引补充

    .unique索引补充:联合唯一 unique(name,email)是name和email这两列联合起来唯一,不再试某个字段唯一 .主键索引,类似唯一索引,也是允许联合多个字段作为主键,例如:pri ...

  9. javascript 值类型和引用类型

    值类型 1. 值类型:string/number/boolean/undefined: 2. 存储:值类型的数据,存储的是数据本身的变量: 3. 赋值:直接将存储的数据复制一份进行赋值,两份数据在内存 ...

  10. 我的日志分析之道:简单的Web日志分析脚本

    前言 长话短说,事情的起因是这样的,由于工作原因需要分析网站日志,服务器是windows,iis日志,在网上找了找,github找了找,居然没找到,看来只有自己动手丰衣足食. 那么分析方法我大致可分为 ...