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 }

时间: 2024-10-13 21:34:01

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

软件工程_东师站_第八周作业

一.PSP Date Type Job Start Interrupt(min) End Total(min) 20160417 助教 黄金点 20:00 5 21:00 55 20160418 助教 黄金点 19:00 12 21:00 108 20160419 助教 黄金点 18:45 100 23:00 155 20160420 助教 团队作业 10:00 35 11:20 45 20160425 结对编程 四则运算 19:00 5 19:30 25 ? 二.进度条 ? 代码行数 博客字数

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

题目貌似有问题 (b) 子问题定义: 设maxValue[i][j]为棋盘的前i行中最后一行为i时第i行按照第j种放置方式放置时得到的最大覆盖值,comp[i][j]为第i种放置方式与第j种放置方式是否相容,value[i][j]为第i行按照第j种放置方式放置时覆盖整数的最大值,如此可以得到递归式. 递归关系: 初值设定: maxValue的行数为棋盘的行数加一,因此令maxValue[0][j]=0表示没有棋盘时值为0 求解顺序: 按从上到下,从左到右的次序求解maxValue的每一行的值,最

POJ 2226-Muddy Fields(二分图_最小点覆盖+神建图orz)

Muddy Fields Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8434   Accepted: 3124 Description Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 50, 1 <= C <= 50). While good for the grass, t

UVA-11419 SAM I AM (最小点覆盖)

题目大意:在一个n*m的网格中,有k个目标,现在可以任选一行或列消除在其上的所有目标,求出最少选择次数及选法. 题目分析:经典的最小点覆盖问题,并且输出一个最小点覆盖集.在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集. 代码如下: # include<iostream> # include<cstdio> # include<cstring> # incl

hdu 1054 Strategic Game 二分图最小点覆盖

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054 题意: 给出一个无向图,求最小点覆盖. 思路: 用网络流来做设立一个超级源点和一个超级汇点. 每个点拆成i和i'. 从超级源点向点i连一条边,容量为1. 从i’向超级汇点连一条边,容量为1. 从i向i'连一条边,容量为正无穷. 然后求最小割/2.因为拆点拆成了2个. 也可以用二分图匹配来做,也是求出最大匹配然后/2. 1 #include <bits/stdc++.h> 2 using na

POJ2226 Muddy Fields(二分图最小点覆盖集)

题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作为XY部,每一块泥地看作边.这样就构造出了一个二分图. 那么,问题就是在这个二分图中就是选出最少的点覆盖所有的边,即二分图最小点覆盖集,而二分图最小点覆盖集=二分图最大匹配. 1 #include<cstdio> 2 #include<cstring> 3 #include<qu

UVa11419 SAM I AM(构造最小点覆盖)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27475 [思路] 二分图的最小点覆盖以及构造最小覆盖. 可见:http://www.tuicool.com/articles/jmAnEb [代码] #include<cstdio> #include<cstring> #include<vector> #include<iostream> using namespace st

POJ3041Asteroids(最小点覆盖+然而并不是很理解why)

Asteroids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18289   Accepted: 9968 Description Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K as

二分图匹配 + 最小点覆盖 - Vertex Cover

Vertex Cover Problem's Link Mean: 给你一个无向图,让你给图中的结点染色,使得:每条边的两个顶点至少有一个顶点被染色.求最少的染色顶点数. analyse: 裸的最小点覆盖问题,二分图的最大匹配,直接套模版即可. Time complexity: O(N^2) view code