一类特殊的模拟费用流模型

news/2025/1/14 17:56:46/文章来源:https://www.cnblogs.com/dan-da-dan/p/18519251

QOJ 7185

题目描述

\(n\) 个学生和 \(k\) 门科目,第 \(i\) 个学生选择第 \(k\) 门科目的消耗为 \(a_{i,j}\) 。第 \(i\) 门科目至多被 \(b_i\) 个学生选择。希望求出每一个学生选择恰好一门科目的最小消耗和。

\(n \leq 5\times 10^4 ,k \leq 10\)

思路点拨

看到这个题目很容易想到一个网络流建模:

  • 一个源点,一个汇点,\(n\) 个代表学生的节点,\(k\) 个代表科目的节点。

  • 学生节点向源点连流量为 \(1\) ,代价为 \(0\) 的边。

  • 科目节点向汇点连流量为 \(b_i\) ,代价为 \(0\) 的边。

  • \(i\) 个同学向第 \(j\) 个科目练流量为 \(1\) ,代价为 \(a_{i,j}\) 的边。

最终该网络的最小费用最大流就是正确答案。相比之下我们更加关心图的性质以及增广路的形态。

经过观察,图具有如下性质:

  • 图是一张二分图,那么每一条增广路除了源点和汇点之外都是左-右-左交替的。

  • 最短路本身的性质:不会经过相同的节点(该网络图不存在负环)。

  • 关键性质:注意到结合上述两个性质,每一条增广路的长度都是 \(O(k)\) 级别的,因为右部点的数量很少。

我们将一次增广路径画出来:

这条增广路有什么具体含义吗?\(2\) 科目有向 \(3\) 学生有流量的边,就意味着 \(2\) 学生选择了 \(3\) 科目。同理, \(5\) 学生选择了 \(6\) 科目。而 \(1\) 学生有向 \(2\) 科目有流量的边,就意味着 \(1\) 学生在此之前没有选择 \(2\) 科目,现在去选择 \(2\) 科目。同理, \(3\) 学生选择 \(4\) 科目,\(5\) 学生选择 \(6\) 科目。

那么我们考虑将路径分为几个部分:

  • 从源点到达第一个左部点,从左部点到达第一个右部点。
  • 对于一个右部点,认为一次移动是"右-左-右"。
  • 右部点经过若干次移动到达最后一个右部点,并走向汇点。

当然,这个路径的权值和需要尽可能的小。

先考虑如何维护出两个右部点 \((i,j)\) 之间的移动 \(i \rightarrow x \rightarrow j\) ,其中 \(x\) 是一个左部节点,需要 \(a_{x,j}-a_{x,i}\) 尽量小才可以。在此移动中,一定有 \(x\) 选择了 \(i\) 科目。不妨对于每一个 \(i,j\) 维护一个堆,堆中保存了选择 \(i\) 科目的全部节点,权值就是 \(a_{x,j}-a_{x,i}\) ,取堆顶就可以了。

那么对于上述路径中的 \(2,3\) 部分,就可以对于右部点建立一张新图:两个节点 \((i,j)\) 之间的权值就是对应堆的堆顶。每一个节点还连向了一个汇点。对此图进行 SPFA ,求出 \(dis_i\) 表示从 \(i\) 科目出发,到达汇点的一个最小费用。

接下来考虑维护第一部分。我们可以枚举第一个右部点 \(j\),去找到最优的,可以到达它的左部点 \(i\)。这个左部点一定满足没有选择这个右部点 ,不妨对于每一个右部点,维护没有选择它的左部点集合,每一次取出 \(a_{i,j}\) 最小的 \(i\) 即可,可以使用一个堆维护。

我们还存在一个问题,就是增广一条路径之后需要做出一些修改操作。具体而言就是部分节点( \(O(k)\) 级别)会更改选择的科目,但是上述我们只是维护了一些堆,换成可删堆就行。

单轮增广的时间复杂度是 \(O(k^3+k^2\log n)\) 。这里 \(O(k^3)\) 来自我们建立新图后的SPFA,\(O(k^2 \log n)\) 是因为我们增广路中有 \(O(k)\) 个左部点,会影响到 \(O(k)\) 个右部点。一个左部点每影响一个右部点 \(i\),就会对于每一个右部点 \(j\) 修改 \((i,j)\) 的移动所对应的堆,这造成 \(O(k^2)\) 次堆删除操作。

一共增广 \(n\) 轮,时间复杂度 \(O(n(k^3+k^2\log n))\)

[AGC018C] Coins

题目描述

\(x+y+z\) 个人,第 \(i\) 个人有 \(A_i\) 个金币,\(B_i\) 个银币,\(C_i\) 个铜币。

要选出 \(x\) 个人获得其金币,选出 \(y\) 个人获得其银币,选出 \(z\) 个人获得其铜币。在不重复选某个人的情况下,最大化获得的币的总数。

\(x+y+z\le 10 ^ 5\)

思路点拨

这个题目可以使用上述模型解决。

对于三个硬币,可以看作上述题目的三个科目。则第 \(i\) 个人向三个硬币连流量为 \(1\) ,代价分别为 \(A_i,B_i,C_i\) 的边。

三个硬币向汇点连流量分别为 \(x,y,z\) ,代价为 \(0\) 的边。求出最大费用最大流即可。

因为本题 \(k=3\) ,所以常数可以忽略。设 \(n=x+y+z\) ,时间复杂度为 \(O(n \log n)\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1e5+5,inf=1e18;
int A,B,C,n;
int a[MAXN][4];
struct heap{priority_queue<pair<int,int>> q1,q2;void push(pair<int,int> x){q1.push(x);}void pop(pair<int,int> x){q2.push(x);}pair<int,int> top(){while(!q2.empty()&&q1.top()==q2.top())q1.pop(),q2.pop();if(q1.empty()) return make_pair(-inf,0);return q1.top();}
}q[4][4],p[4];int e[5][5],dis[5],pre[5];
bool vis[5];
void SPFA(){queue<int> q;for(int i=1;i<=4;i++)dis[i]=-inf,pre[i]=0;dis[4]=0;q.push(4);while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=1;i<=4;i++){if(dis[i]<dis[u]+e[i][u]){dis[i]=dis[u]+e[i][u];pre[i]=u;if(!vis[i]){vis[i]=1;q.push(i);}}} }
}
signed main(){cin>>A>>B>>C;n=A+B+C;for(int i=1;i<=n;i++)for(int j=1;j<=3;j++) cin>>a[i][j];int ans=0;for(int i=1;i<=n;i++)for(int j=1;j<=3;j++) p[j].push(make_pair(a[i][j],i));for(int i=1;i<=n;i++){for(int i=1;i<=3;i++){e[4][i]=e[i][4]=-inf;for(int j=1;j<=3;j++)e[i][j]=q[i][j].top().first;}if(A) e[1][4]=0;if(B) e[2][4]=0;if(C) e[3][4]=0;SPFA();int mx=-inf,id=0;for(int i=1;i<=3;i++)if(p[i].top().first+dis[i]>mx)mx=p[i].top().first+dis[i],id=i;ans+=mx;int pos=id;while(pre[pos]!=4){int u=pos,v=pre[pos];int x=q[u][v].top().second;for(int i=1;i<=3;i++){q[u][i].pop(make_pair(a[x][i]-a[x][u],x));q[v][i].push(make_pair(a[x][i]-a[x][v],x));}pos=pre[pos];}if(pos==1) A--;if(pos==2) B--;if(pos==3) C--;pos=p[id].top().second;for(int i=1;i<=3;i++)p[i].pop(make_pair(a[pos][i],pos));for(int i=1;i<=3;i++)q[id][i].push(make_pair(a[pos][i]-a[pos][id],pos));}cout<<ans;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/825022.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#/.NET/.NET Core优秀项目和框架2024年10月简报

前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项…

低功耗4G模组:MQTT通信功能

​ 今天我们来学习使用合宙Air708E开发板的MQTT通信基本功能。 一、MQTT介绍 MQTT是一种低开销、低带宽占用的即时通讯协议,可以用极少的代码和带宽为远程设备提供实时可靠的消息服务。它适用于硬件性能低下的设备以及网络状况不佳的环境,因此在物联网(IoT)小型设备和移动应…

低功耗4G模组:Air780EP之fskv开发示例

​ 今天我们学习合宙低功耗4G模组Air780EP的fskv开发示例。 一、简介兼容fdb的函数使用fdb的flash空间,启用时也会替代fdb库功能上与EEPROM是类似的fskv与fdb的实现机制导致的差异功能fskvfdbvalue长度4096255key长度6364空间利用率(对比)较低较高读取速度恒定脏数据影响速度,非…

低功耗4G模组HTTP网络协议应用

​ 大家好,今天我们来学习合宙Air780E模组LuatOS开发4G通信中HTTP网络协议的应用,实现模组和服务器之间数据的传输。一、HTTP概述 1.1 简介 HTTP是HyperTextTransferProtocol(超文本传输协议)的缩写。HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。…

2024年10月总结及随笔之漏更及失而复得

2024年10月总结及随笔之漏更及失而复得1. 回头看 日更坚持了670天。读《数据湖仓》更新完成 读《数据工程之道:设计和构建健壮的数据系统》开更并持续更新2023年至2024年10月底累计码字1642797字,累计日均码字2451字。 2024年10月码字86801字,同比下降30.77%,环比下降6.65%…

在系统中部署两个版本JDK实现自由切换(windows

前言 ​ 在学习和工作中遇到不同的项目需要使用不同版本的JDK,可以通过以下办法实现jdk版本自由切换。 准备工作: ​ 准备两种不同版本的jdk(我用的是jdk8和jdk11) 链接附上: https://pan.baidu.com/s/1ZGhVYw6YITLUDJFmfLDGqw?pwd=vuz41.在系统变量中新建: 变量名:CLA…

1 The Ecology of Financial Market

阅读 Trades, Quotes and Prices 的第一章。 Originally Posted at: https://clouder0.com/zh-cn/posts/financial-market-ecology/ How Trade Happens Traditional Way 金融市场都有哪些参与者?他们的各自的目的是什么? 任何交易,总是有两个参与方:Buyer & Seller. 买…

《数字经济产业》

今天,我为大家推荐一篇《数字经济产业集群发展 白皮书》报告。 报告 共 71 页。从 “数字经济概念、特征、典型产业集群案例、要素、策略、产业展望” 等六个方面,详细解读了《2023 数字经济产业》。 很重磅。#01#【关键要点】一、数字经济定义据资源作为关键生产要素、以现代…

requests接口响应出现乱码

在项目里使用requests去请求接口出现一串二进制 如:测试时却显示正常,使用的是另一个项目的虚拟环境(python 3.11.5)切换到本项目中,使用本项目虚拟环境仍然乱码(python3.11.5) 在本项目中尝试切换到3.10,创建一个新的虚拟环境,并保留comment.py脚本只需要的包,仍然报…

CUDA 编程学习 (5)——内存访问性能

现代DRAM结构由于核心速度限制,通过burst模式和多Banks结构提高带宽。CUDA中,warp级聚合内存访问减少DRAM请求,提升效率。分块访问模式通过将数据加载到共享内存中,降低全局内存访问频率,进一步优化CUDA内存访问性能。1. DRAM 带宽 1.1 DRAM 核心阵列结构每个 DRAM 核心阵…

射蜡工序流程图

包含工序:射蜡件、射水溶芯、射尿素芯、化芯、射刺头、射冷蜡块、射牙套、射帽。 前后序:(射芯射配件转至射蜡件)、平行工序(射水溶芯、尿素芯、牙套、刺头) 工序交集点:射水溶芯、射尿素芯 转修蜡修芯 转射蜡件,化芯转修蜡,射蜡首检件转检验,检验合格转修蜡。

定时调度框架Quartz使用

使用背景 在最近的项目中遇到一个需要使用到动态定时任务的需求,即定时任务的调用时间不是在某个固定时间自动执行,而是由用户控制,并且需要持久化。因此在网上搜了一下,发现了一个基于Java开发的Quartz定时任务调度框架,很符合我的需求,因此记录一下便于以后再次使用。 …