Ex 6_21 最小点覆盖问题_第八次作业

子问题定义: 对于图中的每个结点,有两种状态,即属于最小点覆盖和不属于最小点覆盖,定义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 //邻接矩阵表示图、无向无环图
 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 }
View Code
原文地址:https://www.cnblogs.com/xiu68/p/7988924.html