POJ 1149 PIGS 【最大流】
<题目链接>
题目大意:
有一个养猪场,厂长没有钥匙,这个养猪场一共M个猪圈,N个顾客,每个顾客有一些猪圈的钥匙,每个顾客需要一些猪,问你厂长最多能卖多少猪?这里有个条件是,厂长可以在一个顾客买完后,调整没有锁门的猪圈中猪数量,比如,把几个猪圈中的猪全部转到一个猪圈内(这个条件会影响到后期建图),然后再关门,等下一个顾客。
解题分析:
首先根据题意,将这个问题抽象成一个朴素的模型,

因为这样建图,图中最多可能有$2+N+M+N*M (≈1e5)$个节点。在这样的图上跑网络流速度会很慢,我们可以通过合并一些等效的点来达到简化模型的目的。
规律 1. 如果几个结点的流量的来源完全相同,则可以把它们合并成一个。
规律 2. 如果几个结点的流量的去向完全相同,则可以把它们合并成一个。
规律 3. 如果从点 u 到点 v 有一条容量为∞的边,并且点 v 除了点 u 以外没有别的流量来源,则可以把这两个结点合并成一个。
具体简化过程见 >>>
简化后的图为:

因此,最终的建图方案就是:源点到所有第一个打开各个猪圈的人连上一条边,容量为这个猪圈的数量上限,然后,上一个打开这个猪圈的人向下一个打开这个猪圈的人连一条容量为无穷的边,最后,所有人向汇点连一条边,容量为他所能拿的猪数量的上限。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std; typedef long long ll;
const ll INF = 1e18;
const int N = 1e3+; template<typename T>
inline void read(T&x){
x=;int f=;char ch=getchar();
while(ch<''||ch>''){ if(ch=='-')f=-;ch=getchar(); }
while(ch>=''&&ch<=''){ x=x*+ch-'';ch=getchar(); }
x*=f;
}
struct Dinic
{
struct edge{ int from,to;ll cap,flow; };
vector<edge>es;
vector<int>G[N];
bool vis[N];
int dist[N],iter[N];
void init(int n){
for(int i=; i<=n+; i++)G[i].clear();
es.clear();
}
void addedge(int from,int to,ll cap){
es.push_back((edge){from,to,cap,}); //将边存储的边表
es.push_back((edge){to,from,,});
int x=es.size();
G[from].push_back(x-); //G[u][i]记录以u为顶点的第i条边的反边在es中的编号
G[to].push_back(x-);
}
bool BFS(int s,int t){ //bfs将该图划分成分层图
memset(vis,,sizeof(vis));
queue <int> q;
vis[s]=;
dist[s]=;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=; i<G[u].size(); i++){
edge &e=es[G[u][i]];
if(!vis[e.to]&&e.cap>e.flow){
vis[e.to]=;
dist[e.to]=dist[u]+;
q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int u,int t,ll f){
if(u==t||f==)return f;
int lastflow=,d;
for(int &i=iter[u]; i<G[u].size(); i++){
edge &e=es[G[u][i]];
if(dist[u]+==dist[e.to]&&(d=DFS(e.to,t,min(f,e.cap-e.flow)))>){
e.flow+=d; //正边真实流量-d
es[G[u][i]^].flow-=d; //反边真实流量+d
lastflow+=d; //得到现在搜得的能够流入汇点的流量
f-=d; //找到一条增广路之后,减去这条路的流量,然后继续从这个顶点的其它边开始寻找增广路
if(f==)break;
}
}
return lastflow;
}
int Maxflow(int s,int t){
int flow=;
while(BFS(s,t)){
memset(iter,,sizeof(iter));
int d=;
while(d=DFS(s,t,INF))flow+=d;
}
return flow;
}
}dinic; int n,m,st,ed,last[N],pig[N]; //last记录上一个打开对应猪圈的人
int main(){
read(m);read(n);st=;ed=n+;
for(int i=;i<=m;i++) read(pig[i]);
for(int i=;i<=n;i++){
int k;read(k);
while(k--){
int x;read(x);
if(!last[x]) dinic.addedge(st,i,pig[x]),last[x]=i; //如果是第一个打开该猪圈的人,就直接从源点向他连一条边
else dinic.addedge(last[x],i,INF),last[x]=i; //如果这个猪圈已经被打开过了,就从上一个打开的人向他连一条边
}
ll cal;read(cal);
dinic.addedge(i,ed,cal); //每个人向汇点连一条边,容量为他们能够拿的猪的上限
}
cout<<dinic.Maxflow(st,ed)<<endl;
}
POJ 1149 PIGS 【最大流】的更多相关文章
- POJ 1149 - PIGS - [最大流构图]
Time Limit: 1000MS Memory Limit: 10000K Description Mirko works on a pig farm that consists of M loc ...
- poj 1149 pigs ---- 最大流
题意以及分析:http://ycool.com/post/zhhrrm6#rule3 主要是建图,简化图,然后在套最大流的模板. #include <iostream> #include& ...
- poj 1149 pigs(最大流)
题目大意:迈克在农场工作,农场有 m 个猪舍,每个猪舍有若干只猪,但是迈克不能打开任何一间猪舍.有 n 个顾客前来购买,每个顾客有最大的购买数量,每个顾客可以购买某些猪舍的猪,且顾客可以打开这些猪舍, ...
- [poj] 1149 PIGS || 最大流经典题目
原题 题目大意 给你m个猪圈以及每个猪圈里原来有多少头猪,先后给你n个人,每个人能打开一些猪圈并且他们最多想买Ki头猪,在每一个人买完后能将打开的猪圈中的猪顺意分配在这次打开猪圈里,在下一个人来之前 ...
- POJ 1149 PIGS(Dinic最大流)
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20738 Accepted: 9481 Description ...
- poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新
题目大意:是有M个猪圈,N个顾客,顾客要买猪,神奇的是顾客有一些猪圈的钥匙而主人MIRKO却没有钥匙,多么神奇?顾客可以在打开的猪圈购买任意数量的猪,只要猪圈里有足够数量的猪.而且当顾客打开猪圈后mi ...
- 网络流(最大流):POJ 1149 PIGS
PIGS Time Limit: 1000ms Memory Limit: 10000KB This problem will be judged on PKU. 64-bit integer(整数) ...
- POJ 1149 PIGS(最大流)
Description Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock an ...
- poj 1149 PIGS【最大流经典建图】
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18727 Accepted: 8508 Description ...
- poj 1149 PIGS(最大流经典构图)
题目描述:迈克在一个养猪场工作,养猪场里有M 个猪圈,每个猪圈都上了锁.由于迈克没有钥匙,所以他不能打开任何一个猪圈.要买猪的顾客一个接一个来到养猪场,每个顾客有一些猪圈的钥匙,而且他们要买一定数量的 ...
随机推荐
- P1494 [国家集训队]小Z的袜子
题目 P1494 [国家集训队]小Z的袜子 解析 在区间\([l,r]\)内, 任选两只袜子,有 \[r-l+1\choose2\] \[=\frac{(r-l+1)!}{2!(r-l-1)!}\] ...
- Codeforces #381(div2)
A.题目:http://codeforces.com/contest/740/problem/A 题意:现有n本书,买一本书需要花a元,两本书b元,三本书c元,问买够书是4的倍数所需要的最小花费 思路 ...
- rt-thread 之组件与设备初始化配置
@2019-03-08 [小记] rt-thread 初始化配置有两个分支: 第一,板级设备初始化 rt_components_board_init() 第二,内核组件初始化 rt_component ...
- Java大小写转化
java大写转小写 public String toLowerCase(String str){ char[] chars = str.toCharArray(); for (int i = 0; i ...
- postgreSQL学习(二):pgsql的一些基础操作
在上一篇文章中我们学习了怎么安装pgsql,安装好了后,我们来学习一下怎么对pgsql进行创建操作以及相关的crud的操作啦 一 创建数据库 $ createdb test 然后你可能会遇到如下的错误 ...
- DirectX11--HLSL中矩阵的内存布局和mul函数探讨
前言 说实话,我感觉这是一个大坑,不知道为什么要设计成这样混乱的形式. 在我用的时候,以row_major矩阵,并且mul函数以向量左乘矩阵的形式来绘制时的确能够正常显示,并不会有什么感觉.但是也有人 ...
- HTML(二)HTML元素(整体结构,块级元素,内联元素,结构元素,交互元素,元素嵌套规则)
HTML整体结构解释 <!DOCTYPE html> // 文件应以"<!DOCTYPE ......>"首行顶格开始,推荐使用"<!DOC ...
- Java中多态性的实现
class A ...{ public String show(D obj)...{ return ("A and D"); } public String show(A obj) ...
- installshield安装包制作
入门教程:http://blog.csdn.net/gaofang2009/article/details/5260065 入门教程:http://blog.csdn.net/plfl520/arti ...
- sea.js 个人入门
玉伯 : http://seajs.org/docs/ 说这两个JS 必须提到AMD.commonjs两种不同的规范: 奇舞团:http://www.75team.com/archives/882 知 ...