分支限界法之最小权顶点覆盖问题 您所在的位置:网站首页 最大集合覆盖问题是什么 分支限界法之最小权顶点覆盖问题

分支限界法之最小权顶点覆盖问题

2024-07-16 13:33| 来源: 网络整理| 查看: 265

问题描述

在这里插入图片描述

题目分析

我们先简明介绍一下题目,我们仍然需要将所有点分成U、V两个集合。什么叫做顶点覆盖呢?即为V 集合中的每个点,至少与一个U集合中的点直接相连。如图所示(红色点表示U集合中的点): 在这里插入图片描述 我们可以看到V集合中的顶点2、5、6,都与至少一个U集合中的顶点直接相连。反而如果按照下图分配则不满足条件: 在这里插入图片描述图中V集合的顶点2、5并没有U集合中的点与其直接相连,所以不是一种顶点覆盖。

那我们应该如何判断图是否被覆盖了呢?可以开辟一个数组c,如果c[j]==0,则表示U集合中没有任何一个顶点与其直接相连。 优先级 说完如何判断是否覆盖之后,我们来确定一下优先级。由于所有顶点都是带权的,我们的目的也是找到最小权覆盖,所以我们可以直接用权重作为优先级建立一个最小堆,从而实现优先队列。 界限函数 我们找的是最小点权,无法使用界限函数来对右孩子进行约束,因为如果当前结点不加入U集合中(即走右孩子路径),一定点权和更小,但是不一定会覆盖,所以不经过判断,我们也要将右孩子加入到队列中。 将活结点加入队列中 将活结点加入队列时,要对点的优先级、结果向量以及cover数组进行更新。

代码 #include #include using namespace std; class HeapNode { friend class VC;//求解最小权覆盖问题的类,融合了所有函数和所需的参数 public: operator ()(int x,int y) const{return x priority_queue H(100000); HeapNode E//扩展结点 E.x = new int [n+1];//开辟结果向量 E.c = new int [n+1];//开辟一数组,用于判断图是否被完全覆盖 for(int j = 1;j if(i > n) { if(cover(E)) { for(int j = 1;j for(int j = 1;j return false; } } return true; } void VC::AddLiveNode(priority_queue &H,HeapNode E,int cn,int i,bool ch) { HeapNode N;//创建一个新的堆结点 N.x = new int [n+1]; N.c = new int [n+1]; for(int j = 1;j N.cn = cn + w[i];//此时i要加入集合U,所以其权重应该加上cn for(int j = 1;j VC Y; Y.w = new int [n+1]; for(int j = 1;j for(int j = 0;j cin>>u>>v; a[u][v] = 1; a[v][u] = 1; } cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有