Sell Pigs 题解
题目大意
有 \(n\) 个顾客前来买猪,共有 \(m\) 个猪圈,每个顾客携带着某一些猪圈的钥匙,需要买一定数量的猪。在顾客买完后,我们可以将打开的猪圈中的猪随意移动,移动完毕后所有的猪圈将关闭,直到下一个顾客到来时才能打开其拥有钥匙对应的猪圈。求最多能卖出多少猪。
思路分析
我们注意到顾客是有时间顺序的。因此,我们首先想到可以建立一张分层图,每个点 \((a,b)\) 表示在第 \(a\) 个顾客到来时的第 \(b\) 个猪圈, 那么边的设置就很自然:
- 建立虚拟源点和汇点,源点向每个 \((1,x)\) 点连边,边权为初始的数量。
- 对于每一层再建一个点,将该层所有被打开的点向它连边,同时它向下一层对于的点连边,边权均为 \(+\infty\),再将其向汇点连边,边权为 \(+\infty\)。

然后跑最大流就可以了。
但是,这样的空间复杂度是 \(O(nm)\) 的,时间复杂度更是高达 \(O(n^3m^3)\),是比较劣的,如何优化呢?
既然顾客有时间顺序,那么我们不妨从顾客下手,只建立 \(n\) 个代表顾客的点,那么如何连边呢?
- 建立虚拟源点,汇点。
- 每个点向汇点连边,边权是这个顾客对猪的需求量。
- 记录每个猪圈最近一次是被谁打开的,如果是第一次打开,将从源点向这个顾客连的边的边权增加这个猪圈的猪的数量。(如果没有这条边就建立这条边)
- 如果不是第一次打开,将上一次打开这个猪圈的顾客向这个顾客连一条边权是 \(+\infty\) 的边。

然后跑最大流就可以了。
空间复杂度 \(O(n)\),时间复杂度 \(O(n^3)\)。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=100100;
#define inf 0x3f3f3f3f
int to[N],nxt[N],head[N],w[N];
int idx=1,n,m,S,T,in1,in2;
int d[N],cur[N];queue <int> q;
int a[N],vis[N];//a 是猪圈中猪的数量,vis 保存上一次打开的人
void add(int u,int v,int c){
idx++;to[idx]=v;nxt[idx]=head[u];head[u]=idx;w[idx]=c;
idx++;to[idx]=u;nxt[idx]=head[v];head[v]=idx;w[idx]=0;
}
//dinic模板默写
bool bfs(){
memset(d,-1,sizeof d);d[S]=0;
while(!q.empty()) q.pop();
cur[S]=head[S];q.push(S);
while(!q.empty()){
int now=q.front();q.pop();
for(int i=head[now];i;i=nxt[i]){
int v=to[i];
if(~d[v]||!w[i]) continue;
d[v]=d[now]+1;cur[v]=head[v];
if(v==T) return 1;q.push(v);
}
}
return 0;
}
int dfs(int s,int lim){
if(s==T) return lim;
int flow=0;
for(int i=cur[s];i&&flow<lim;i=nxt[i]){
int v=to[i];cur[s]=i;
if(d[v]!=d[s]+1||!w[i]) continue;
int t=dfs(v,min(w[i],lim-flow));
if(!t) d[v]=-1;
w[i]-=t;w[i^1]+=t;flow+=t;
}
return flow;
}
int dinic(){
int ans=0,flow=0;
while(bfs()) while(flow=dfs(S,inf)) ans+=flow;
return ans;
}
//------
int main(){
scanf("%d%d",&m,&n);
S=0;T=N-2;//虚拟源汇点
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
scanf("%d",&in1);
int sum1=0;
for(int j=1;j<=in1;j++){
scanf("%d",&in2);
if(!vis[in2]){sum1+=a[in2];}//增加边权
else add(vis[in2],i,inf);//上一个人向这个人连边
vis[in2]=i;//更新这个猪圈
}
if(sum1) add(S,i,sum1);
scanf("%d",&in1);
add(i,T,in1);//向汇点连边
}
cout<<dinic()<<'\n';
return 0;
}
Sell Pigs 题解的更多相关文章
- POJ1149:PIGS——题解
http://poj.org/problem?id=1149 题目大意: Mirko有M个猪圈和N个客户,猪圈里有特定数量的猪,每个客户按照顺序来买猪,他们只能打开他们能打开的猪圈,然后取走一些猪(上 ...
- [Leetcode Week6]Best Time to Buy and Sell Stock
Best Time to Buy and Sell Stock 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/best-time-to-buy-and ...
- [LeetCode 题解]:Best Time to Buy and Sell Stock
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Say you ha ...
- Lintcode393 Best Time to Buy and Sell Stock IV solution 题解
[题目描述] Say you have an array for which the i th element is the price of a given stock on day i. Desi ...
- [LeetCode]题解(python):123-Best Time to Buy and Sell Stock III
题目来源: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ 题意分析: 和上题类似,array[i]代表第i天物品 ...
- [LeetCode]题解(python):122-Best Time to Buy and Sell Stock II
题目来源: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ 题意分析: 和上题类似,给定array,代表第i天物品i ...
- [LeetCode]题解(python):121-Best Time to Buy and Sell Stock
题目来源: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ 题意分析: 给定一个数组,代表array[i] 代表第i天的价 ...
- 题解 POJ1149 Pigs
先翻译一下吧(题面可以在原OJ上找) Mirko在一个由M个锁着的猪舍组成的养猪场工作,Mirko无法解锁任何猪舍,因为他没有钥匙.客户纷纷来到农场.他们每个人都有一些猪舍的钥匙,并想购买一定数量的猪 ...
- CF116B Little Pigs and Wolves 题解
Content 有一张 \(n\times m\) 的地图,其中,\(\texttt{P}\) 代表小猪,\(\texttt{W}\) 代表狼.如果狼的上下左右有一头以上的小猪,那么它会吃掉其中相邻的 ...
- [题解] Codeforces 1548 C The Three Little Pigs 组合数学,生成函数
题目 首先令\(x=i\)时的答案为\(f_i\) ,令\(f_i\)对应的普通生成函数为\(F(x)\). 很容易发现\(F(x)=\sum_{i=0}^n (1+x)^{3i}\),sigma是在 ...
随机推荐
- 写博文之必备技能MarkDown
前言 Markdown是一种轻量级标记语言,排版语法简洁,让人们更多地关注内容本身而非排版.它使用易读易写的纯文本格式编写文档,可与HTML混编,可导出 HTML.PDF 以及本身的 .md 格式的文 ...
- 好用到飞起的新项目「GitHub 热点速览」
虽然本周 GitHub 热榜都是一些熟悉的面孔,但还是有不少新开源的项目,比如受启发于 Stripe IDs 的 UUIDv7 扩展 typeid,相信有了它,数据标识问题就迎刃而解了.此外,还有刚开 ...
- Java_Day16_作业
A:简答题 1.请把我们讲解过的所有类中的方法在API中找到,并使用自己的话进行描述 答案: Map public V put(K key, V value): public void clear() ...
- VS2017配置OpenCV
VS2017配置OpenCV 0 OpenCV介绍 OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉算 ...
- 正确处理 CSV 文件的引号和逗号
CSV(Comma-Separated Values,逗号分割值),就是用纯文本的形式存储表格数据,最大的特点就是方便. 作为开发,我们经常面临导数据的问题,特别是后台系统,产品或者运营的同事常常会提 ...
- 2023-07-20:假设一共有M个车库,编号1~M,时间点从早到晚是从1~T, 一共有N个记录,每一条记录如下{a, b, c}, 表示一辆车在b时间点进入a车库,在c时间点从a车库出去, 一共有K
2023-07-20:假设一共有M个车库,编号1 ~ M,时间点从早到晚是从1 ~ T, 一共有N个记录,每一条记录如下{a, b, c}, 表示一辆车在b时间点进入a车库,在c时间点从a车库出去, ...
- DolphinScheduler3.1.7集成SAP HANA
源码地址:GitHub - apache/dolphinscheduler at 3.1.7-release 个人fork gitee地址:DolphinScheduler:Gitee) 后端代码更改 ...
- hdfs小文件合并
HDFS small file merge 1.hive Settings There are 3 settings that should be configured before archivin ...
- 在 Arch 配置 i3-wm 终端模拟器 xterm
在 Arch 配置 i3-wm 终端模拟器 xterm 关于怎么在 Arch 安装 i3-wm 可以查看上一篇文章 https://www.cnblogs.com/shadow-/p/17572589 ...
- Redis从入门到放弃(1):安装配置
1. 介绍 Redis是一个高性能的开源key-value数据库.它被广泛应用于缓存.会话存储.实时分析.消息队列等场景.Redis具有以下三个主要特点: 数据持久化:Redis支持将内存中的数据保存 ...