当前位置: 首页 > news >正文

最小支配集讲解

 

定义

最小支配集:对于图G = (V, E) 来说,最小支配集指的是从 V 中取尽量少的点组成一个集合,

使得 V 中剩余的点都与取出来的点有边相连.也就是说,设 V' 是图的一个支配集,则对于图

中的任意一个顶点 u ,要么属于集合 V', 要么与 V' 中的顶点相邻. 在 V' 中除去任何元素后

V' 不再是支配集, 则支配集 V' 是极小支配集.称G 的所有支配集中顶点个数最少的支配集

为最小支配集,最小支配集中的顶点个数称为支配数.

求解

贪心策略:首先选择一点为树根,再按照深度优先遍历得到遍历序列,按照所得序列的反向序列的顺序进行贪心,对于一个即不属于支配集也不与支配集中的点相连的点来说,如果他的父节点不属于支配集,将其父节点加入到支配集.

伪代码:

  第一步:以根节点深度优先遍历整棵树,求出每个点在深度优先遍历序列中的编号和每个点的父节点编号.

  第二步:按照深度优先遍历的反向顺序检查每个点,如果当前点不属于支配集也不与支配集的点相连,且它的父节点不属于支配集,将其父节点加入到支配集,支配集中点的个数加 1, 标记当前节点, 当前节点的父节点, 当前节点的父节点的父节点,因为这些节点要么属于支配集(当前点的父节点),要么与支配集中的点相连(当前节点 和 当前节点的父节点的父节点).

具体实现:

  采用链式前向星存储整棵树.整形数组newpos[i] 表示深度优先遍历序列的第 i 个点是哪个点, now 表示当前深度优先遍历序列已经有多少个点了. bool形数组visit[]用于深度优先遍历的判重,整形pre[i]表示点 i 的父节点编号,  bool型数组s[i]如果为 true, 表示第 i 个点被覆盖, bool型数组set[i]如果为 true,表示点 i 属于要求的点的集合.

代码

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1000;
int pre[maxn];//存储父节点
bool visit[maxn];//DFS标记数组
int newpos[maxn];//遍历序列
int now;
int n, m;

int head[maxn];//链式前向星
struct Node {int to; int next;};
Node edge[maxn];

void DFS(int x) {
    newpos[now ++] = x;//记录遍历序列
    for(int k = head[x]; k != -1; k = edge[k].next) {
        if(!visit[ edge[k].to ]) {
            visit[ edge[k].to ] = true;
            pre[edge[k].to] = x;//记录父节点
            DFS(edge[k].to);
        }
    }
}

int MDS() {
    bool s[maxn] = {0};
    bool set[maxn] = {0};
    int ans = 0;
    for(int i = n - 1; i >= 0; i--) {//逆序进行贪心
        int t = newpos[i];
        if(!s[t]) { //如果当前点没被覆盖
            if(! set[ pre[t] ]) {//当前点的父节点不属于支配集
                set[ pre[t] ] = true;//当前点的父节点加入支配集
                ans ++;  //支配集节点个数加 1
            }
            s[t] = true; //标记当前点已被覆盖
            s[ pre[t] ] = true;// 标记当前点的父节点被覆盖
            s[ pre[ pre[t] ] ] = true;//标记当前点的父节点的父节点被覆盖
        }
    }
    return ans;
}

int main() {
    /* read Graph message*/ //建图
    memset(visit, false, sizeof(visit));//初始化
    now = 0;
    visit[1] = true;
    pre[1] = 1;
    DFS(1);//从根节点开始寻摘遍历序列
    MDS();
    return 0;
}
View Code

 

 

转载:http://www.cnblogs.com/Ash-ly/p/5775934.html

转载于:https://www.cnblogs.com/Kissheart/p/9939887.html

相关文章:

  • JS事件类型
  • ansible批量管理工具
  • json 序列化和反序列化的3个方法
  • Mac 启动 ssh 服务
  • Logstash 6.4.3 导入 csv 数据到 ElasticSearch 6.4.3
  • 指定spring中bean启动的顺序
  • utp
  • 把图片上的文字转换成word文字?
  • Ajax请求参数到一个URL包含下划线或者v(_、v)
  • Hibernate基础入门
  • Sitecore 9有什么新功能
  • r语言
  • redis入门学习记录(一)
  • Python并发编程之协程
  • A. A Prank
  • .pyc 想到的一些问题
  • “大数据应用场景”之隔壁老王(连载四)
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • crontab执行失败的多种原因
  • css布局,左右固定中间自适应实现
  • javascript 总结(常用工具类的封装)
  • JavaScript-Array类型
  • react-native 安卓真机环境搭建
  • Vue实战(四)登录/注册页的实现
  • 成为一名优秀的Developer的书单
  • 检测对象或数组
  • 前端面试之CSS3新特性
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 原生js练习题---第五课
  • 你对linux中grep命令知道多少?
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • 1.Ext JS 建立web开发工程
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • #每日一题合集#牛客JZ23-JZ33
  • $().each和$.each的区别
  • (30)数组元素和与数字和的绝对差
  • (9)目标检测_SSD的原理
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (过滤器)Filter和(监听器)listener
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (转)【Hibernate总结系列】使用举例
  • (转)为C# Windows服务添加安装程序
  • **PHP分步表单提交思路(分页表单提交)
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET DataGridView数据绑定说明
  • .net mvc 获取url中controller和action
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually
  • [ C++ ] STL---仿函数与priority_queue
  • [Asp.net mvc]国际化
  • [BZOJ1178][Apio2009]CONVENTION会议中心
  • [C#]winform利用seetaface6实现C#人脸检测活体检测口罩检测年龄预测性别判断眼睛状态检测