网络流经典模型——最大权闭合子图

2023-10-27

网络流经典模型——最大权闭合子图

  1. 什么是闭合子图

    闭合子图的概念 : 通俗点说就是选出一个图的子图,使得子图中的所有点出度指向的点依旧在这个子图内,则说明此子图是闭合子图。如下图

  2. 最大权闭合子图 : 假设每个点具有点权值,在一个图的所有闭合子图中,点权之和最大的即是最大权闭合子图

  3. 最大权闭合子图与最小割的关系

    这里我们要证明最大权闭合子图的权值之和与最小割的关系

    结论:最小割所产生的两个集合中,其源点S所在集合(除去S)为最大权闭合图

    • 证明:最小割为简单割。

      因为除S和T之外的点间的边的容量是正无穷,最小割的容量不可能为正无穷。所以,得证

    • 证明网络中的简单割与原图中闭合图存在一一对应的关系

      证明闭合图是简单割:如果闭合图不是简单割(反证法)。那么说明有一条边是容量为正无穷的边,则说明闭合图中有一条出边的终点不在闭合图中,矛盾。

      证明简单割是闭合图:因为简单割不含正无穷的边,所以不含有连向另一个集合(除T)的点,所以其出边的终点都在简单割中,满足闭合图定义。得正。

    • 证明最小割所产生的两个集合中,其源点S所在集合(除去S)为最大权闭合图

      证明比较简单,记录结论就好了

  4. 如果对最大权闭合子图建模

    首先,我们有结论,最大权闭合子图权值 = 所有权值为正的权值之和 - 最大流

    所以,

    (1)如果当前点权值为正,建边s到u,容量为权值w;

    (2)如果当前点权值为负,建边u到t,容量为权值的绝对值|w|

    (3)在原图中存在的边,建边u到v,容量为INF,表示如果需要切断v就必须切断u,否则有一条容量为INF的边就不是最小割了。(就是通过这样的限制方式实现)

    最后,上图的模型转化为

    img

例题:(1)师范大学の矿山

给你n个石头,每个石头有一个价值val,有一个花费cost,在挖当前石头时,如果有石头挡在当前石头前面,只有当你挖掉前面的石头后,才能挖现在的石头,问你最小花费。

思路:最大权闭合子图裸题,对于每个石头,如果val-cost>0,建边s到i,如果val-cost<0,建边i到t,在原图中的图,建立反向图就好了,容量为INF。

(水题不要代码)

(2)BZOJ1497最大获利

对于两个点u,v,建立两个点的花费为costa+costb,但是可以获得c的利润,问你最后最大获利为多少

思路:

都告诉你最大权闭合子图了,那就往这方面想,将边权值化为点权值,比如边(u,v,w),将他抽象为一个点x,这个点可以获利,于是他应该与源点s相连;点u,v都只能亏损(建立点的花费),向汇点建边;最后x与u,v都要建边,容量为INF,表示如果选择c,那么u和v都要选择。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
​
const int maxn=60000+15;
const int INF=0x3f3f3f3f;
struct Edge{
    int from,to,cap,flow;
    Edge(int a,int b,int c,int d):from(a),to(b),cap(c),flow(d){}
};
struct Dinic{
    int n,m,s,t;
    vector<int>G[maxn];
    vector<Edge>edges;
    int d[maxn];
    int vis[maxn];
    int cur[maxn];
    void init(int n){
        this->n=n;
        for(int i=0;i<=n;i++)G[i].clear();
        edges.clear();
    }
    void add_edges(int u,int v,int cap){
        edges.push_back(Edge(u,v,cap,0));
        edges.push_back(Edge(v,u,0,0));
        m=edges.size();
        G[u].push_back(m-2);
        G[v].push_back(m-1);
    }
    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int> Q;//用来保存节点编号的
        Q.push(s);
        d[s]=0;
        vis[s]=true;
        while(!Q.empty())
        {
            int x=Q.front(); Q.pop();
            for(int i=0; i<G[x].size(); i++)
            {
                Edge& e=edges[G[x][i]];
                if(!vis[e.to] && e.cap>e.flow)
                {
                    vis[e.to]=true;
                    d[e.to] = d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
​
    //a表示从s到x目前为止所有弧的最小残量
    //flow表示从x到t的最小残量
    int DFS(int x,int a)
    {
        if(x==t || a==0)return a;
        int flow=0,f;//flow用来记录从x到t的最小残量
        for(int& i=cur[x]; i<G[x].size(); i++)
        {
            Edge& e=edges[G[x][i]];
            if(d[x]+1==d[e.to] && (f=DFS( e.to,min(a,e.cap-e.flow) ) )>0 )
            {
                e.flow +=f;
                edges[G[x][i]^1].flow -=f;
                flow += f;
                a -= f;
                if(a==0) break;
            }
        }
        if(!flow) d[x] = -1;///炸点优化
        return flow;
    }
​
    int Maxflow(int s,int t)
    {
        this->s=s,this->t=t;
        int flow=0;
        while(BFS())
        {
            memset(cur,0,sizeof(cur));
            flow += DFS(s,INF);
        }
        return flow;
    }
};
Dinic dinic;
​
int n,m;
int val[maxn];
signed main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        dinic.init(n+10);
        int inx=n;
        int s=0,t=n+m+10;
        for(int i=1;i<=n;i++){
            int w;
            scanf("%d",&w);
            dinic.add_edges(i,t,w);
        }
        int tot=0;
        for(int i=1;i<=m;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            int inx=n+i;
            tot+=w;
            dinic.add_edges(s,inx,w);
            dinic.add_edges(inx,u,INF);
            dinic.add_edges(inx,v,INF);
        }
        int ans=dinic.Maxflow(s,t);
        printf("%d\n",tot-ans);
    }
    return 0;
}
​

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网络流经典模型——最大权闭合子图 的相关文章

  • True Liars 【POJ - 1417】【种类并查集+0-1背包】

    题目链接 题目想要知道有P个好人 说真话的人 和Q个坏人 说假话的人 并且有N条信息 代表A说B是好人 yes 坏人 no 那么 在保证答案唯一的情况下输出这P个好人 并且最后的时候输出 end 否则 输出 no 坑点 答案唯一指的是最后你
  • C#字典树(字母树)的模板

    保存一下JimLiu大神的 既然JimLiu大神的这个 net博客不维护了 我就搬过来了 哈哈哈 希望JimLiu大神不要见怪
  • hdu 2586 How far away ?

    Problem acm hdu edu cn showproblem php pid 2586 Meaning 给一棵 n 个点的树 和 n 1 条边的边权 多次询问树上两点的距离 Analysis 以任意顶点为根 DFS 预处理出所有结点
  • lambda

    外部变量访问方式说明符 不捕获任何变量 以引用方式捕获所有变量 用值的方式捕获所有变量 可能被编译器优化为const foo 以引用捕获foo 但其余变量都靠值捕获 foo 以值捕获foo 但其余变量都靠引用捕获 bar 以值方式捕获bar
  • Supermarket 【POJ - 1456】【并查集+哈希表思想+贪心】

    题目链接 原来 并查集还有这样的作用 题记 我想用个哈希表的思维来解这道题 但是 显然O N 2 的哈希表去查询并插入显然是不行的 那么既然挂在图论专题 我就得用相应的方式解答咯 要是不挂在图论专题 我可能会自闭了 我们对于每个物品按照价值
  • XYZZY 【POJ - 1932】【SPFA】

    题目链接 有N个点 然后输入1 N个点 输入从它到其他点的血量变化 然后有几个点能到达 最后是这几个点 我们起点为1 终点为N 然后求的是我们是不是有可能或者达到终点 gt 0 直接SPFA跑最长路 感觉是在造样例 6 0 1 2 1000
  • template之模板注意事项

    前言 在分析STL之前 我们需要先对template做一个回忆 可能我总结的内容你都会了 也可能你没有了印象了 但是我还是希望你先浏览一下template的用法 毕竟STL全部都涉及到了模板 而template是学习STL的基础 templ
  • The Stable Marriage Problem 【HDU - 1914】【稳定婚姻匹配问题】

    题目链接 Problem Description The stable marriage problem consists of matching members of two different sets according to the
  • 矩阵树定理

    启蒙 http zhengruioi com contest 1416 T1 T2的10分暴力 后面是论文科技 不搞了 https www luogu com cn problem P6178 O n 3
  • 以模板的方式重载"operator <<"需要注意的地方

    当我们用C 进行后台开发的时候 常常需要知道某一时刻一个容器的内容 通常 我们的做法是利用迭代器将容器内容打印到日志文件中 然后进行观察分析 如果每次打印都去找迭代器的麻烦 显然不是我们想要的 这样 顺理成章的我们就想到了封装函数 为了更方
  • 迪杰斯特拉算法浅析

    所谓的迪杰斯特拉算法 就是一个用来求一个图中某点到其它点的最短路径的算法 大致方法 遍历所有节点 找到离起点最近的一个点 那么这个点到起点的最小距离肯定是起点到这个点的这条边的权值 然后标记这个点被使用过了 以1中的那个点为中继 更新其它节
  • [图论]---[网络流]---最大权闭合子图

    最大权闭合子图 闭合图的概念 闭合图建立在有向图之上 对于 G V E 选取一个点的子集 V V 的任意一点的所有能到达的点也在集合 V 内 则称 V 为闭合子图 最大权闭合子图即在G的所有闭合子图中 点权和最大的 最大权闭合子图的求法 构
  • 最长公共上升子序列(LCIS)

    前置知识 LCS LIS 注意 刚开始看这个问题的时候 第一反应是先求出LCS再求出LCS的LIS 事实上这是有问题的 我们并不能保证这么求出的LCIS是最长的 比如下面这个例子 Example a 7 1 5 6 4 2 7 b 7 1
  • [NOI 2015复习][BZOJ 1509][NOI 2003]逃学的小孩(树的直径)

    题目链接 http www lydsy com JudgeOnline problem php id 1509 题目大意 要从一棵树中找出三个点 X Y Z X Y Z 使得 min dis A C dis B C dis A B min
  • 蓝桥杯 题库 简单 每日十题 day2

    01 卡片 题目描述 本题为填空题 只需要算出结果后 在代码中使用输出语句将所填结果输出即可 小蓝有很多数字卡片 每张卡片上都是数字 0 到 9 小蓝准备用这些卡片来拼一些数 他想从 1 开始拼出正整数 每拼一个 就保存起来 卡片就不能用来
  • How far away ? 【HDU - 2586】【DFS+链式前向星优化】

    题目链接 其实这道题可以不用链式前向星优化换做vector lt gt 也是可以跑的 只是会许会慢些而已 来换个中文题意好读些 勇气小镇是一个有着n个房屋的小镇 为什么把它叫做勇气小镇呢 这个故事就要从勇气小镇成立的那天说起了 修建小镇的时
  • 数据结构算法—邻接表存储的无向图求连通分量个数

    数据结构算法 邻接表存储的无向图求连通分量个数 邻接表存储结构 typedef struct ArcNode int adjvex 边指向的顶点 struct ArcNode nextarc 下一条边的指针 ArcNode typedef
  • 图论--最近公共祖先LCA

    最近公共祖先LCA LCA Least Common Ancestors 即最近公共祖先 是指这样一个问题 在有根树中 找出某两个结点u和v最近的公共祖先 另一种说法 离树根最远的公共祖先 最近公共祖先是相对于两个节点来说的 一般来说 最近
  • Binary Tree on Plane【费用流】

    题目链接 CF 277 E 题意翻译 给你平面上 n 个点 2 n 400 要求用这些点组成一个二叉树 每个节点的儿子节点不超过两个 定义每条边的权值为两个点之间的欧几里得距离 求一个权值和最小的二叉树 并输出这个权值 其中 点 i 可以成
  • 860.染色法判定二分图

    二分图是指一个图中的所有顶点可以分为两部分 并且每条边连接的是属于不同部分的两个顶点 include

随机推荐

  • 2022年度笔记本十大热门品牌销量排行榜

    近年来 由于大环境的改变 线上教育 线上办公等的需求使得平板电脑出货量逐步提升 同时 5G时代来临 万物互联是未来的趋势 手机由于操作系统和交互上的局限性 笔记本电脑将会扮演更加重要的角色 未来 整个笔记本电脑行业的空间有望进一步打开 根据
  • 数据结构代码——折半插入排序

    折半插入排序的算法思想可以参考王道数据结构的书 建议先看书或者通过B站学习相关课程了解算法思想后再看代码 代码 define CRT SECURE NO WARNINGS 1 define ElemType int include
  • 什么是Token(令牌)

    Acess Token 访问资源接口 API 时所需要的资源凭证 简单token 的组成 uid 用户唯一的身份标识 time 当前时间的时间戳 sign 签名 token的前几位以hash算法压缩成的一定长度的16进制字符串 特点 服务端
  • centos7 systemctl 命令详解

    Systemctl 命令简介 定义 systemctl一个系统管理守护进程 工具和库的集合 用于取代System V service和chkconfig命令 功能 systemctl 主要用于查询或发送控制命令给systemd服务 管理单元
  • 执行查看数据库表空间信息报错 ORA-01116、ORA-01110、ORA-27041

    查看剩余表空间大小 SELECT tablespace name 表空间 sum blocks 8192 1000000 剩余空间M FROM dba free space GROUP BY tablespace name ORA 0111
  • Django(8)-静态资源引用CSS和图片

    除了服务端生成的 HTML 以外 网络应用通常需要一些额外的文件 比如图片 脚本和样式表 来帮助渲染网络页面 在 Django 中 我们把这些文件统称为 静态文件 我们使用static文件来存放静态资源 django会在每个 INSTALL
  • pip install 出现Could not install packages due to an EnvironmentError: [WinError 5] 拒绝访问

    pip install U numpy进行更新的时候出现了上述的问题 百度了一下直接在install后面加上 user 就可以了 pip install user upgrade numpy
  • 使用ffmpeg对rtsp视频截图

    ffmpeg i rtsp 192 168 1 64 554 Streaming Channels 1 y f mjpeg t 0 001 s 1280x720 test jpg 使用ffmpeg对摄像头的视频流进行截图 rtsp 192
  • Linux内网环境安装nginx,离线安装nginx教程

    说明 本教程针对内网环境 没有互联网环境 安装nginx 安装前测试 nginx未安装时 无法访问 curl http localhost 80 第一步 请参考教程 本地yum源安装 教程连接如下 https note youdao com
  • IDEA在XML中提示SQL

    首先配置Database 选择数据库类型之后 填写数据库配置 配置完成之后右键表名 mybatis generator生成从controller dao单表的代码 Jump to Query Console跳转到IDEA编写SQL的页面 非
  • Stable Diffusion界面参数及模型使用

    系列文章目录 本地部署Stable Diffusion教程 亲测可以安装成功 谷歌Colab云端部署Stable Diffusion 进行绘图 文章目录 系列文章目录 前言 Stable Diffusion界面参数 一 模型是干什么的 二
  • uniapp引入iconfont图标

    1 iconfont官网下载好图标并解压 2 将以下文件复制到项目中 3 文件在项目中的位置 4 打开iconfont css文件修改 font face 里面的路径 修改为相对路径 static fonts 示例如下 5 在App vue
  • 利用mysql load data秒级别大批量写入数据,建议单次10w+以上~速度远超批量insert,附上完整封装工具

    平时项目中 有时候可能会遇到需要大批量写入数据到mysql数据库中的场景 这时候我们可以利用mysql自带的load data语法 先将数据写入文本文件 再将文件读入数据库 具体用法看下面 1 表结构如下 CREATE TABLE wewo
  • Win10家庭版禁用系统更新方法汇总及问题解决

    这个文章针对没有组策略gpedit msc的win10家庭版 网上有几种方法 我在这里汇总一下 并记录之后遇到的问题及 一 先启用组策略 然后禁止更新 1 启用组策略 win10家庭版是没有组策略gpedit msc的 在电脑任意位置创建一
  • 微软宣布在 Excel 中使用 Python:结合了 Python 的强大功能和 Excel 的灵活性。

    文章目录 Excel 中的 Python 有何独特之处 1 Excel 中的 Python 是为分析师构建的 高级可视化 机器学习 预测分析和预测 数据清理 2 Excel 中的 Python 通过 Anaconda 展示了最好的 Pyth
  • C语言基础系列(三)——链表

    C语言基础系列 三 链表 1 链表的定义 链表是一些包含数据的独立结构体 被称为节点 的集合 1 1 单链表 在单链表中 每个节点包含一个指向链表下一节点的指针 示意图如下 定义的节点结构体声明如下 typedef struct NODE
  • 合宙Air103

    目录 基础资料 探讨重点 实现功能 硬件准备 软件版本 软件使用 初始化硬件i2c 发送指令给AHT10触发测量并读数 状态位说明 读取流程 核心函数注 基础资料 基于Air103开发板 Air103 LuatOS 文档 上手 开发上手 L
  • Swagger3快速入门

    Swagger 快速入门SpringBoot集成Swagger 依赖 配置类 SwaggerConfig 访问 配置Swagger 可以通过apiInfo 属性配置文档信息 完整版 访问 controller 测试接口 正则表达式设置路径范
  • 数据结构 每日一练:选择 + 编程

    目录 选择 编程 选择 1 在一个单链表中 已知q所指结点是p所指结点的前驱结点 若在q和p之间插入结点s 则执行 A s gt next p gt next p gt next s B p gt next s gt next s gt n
  • 网络流经典模型——最大权闭合子图

    网络流经典模型 最大权闭合子图 什么是闭合子图 闭合子图的概念 通俗点说就是选出一个图的子图 使得子图中的所有点出度指向的点依旧在这个子图内 则说明此子图是闭合子图 如下图 最大权闭合子图 假设每个点具有点权值 在一个图的所有闭合子图中 点