http://poj.org/problem?id=1149

题目大意:

Mirko有M个猪圈和N个客户,猪圈里有特定数量的猪,每个客户按照顺序来买猪,他们只能打开他们能打开的猪圈,然后取走一些猪(上限为每个人特定的值b),Mirko在每个客户来之后将该客户打开的猪圈内剩余的猪重新分配到该客户打开的猪圈内。

求最大取猪数量。

——————————————————————

看到n和m的数量级为网络流。

很容易能够想到一种建图方法:

1.将每个猪圈拆成N个点(代表第N个客户来的时刻每个猪圈的状态),源点连到每个猪圈第一个点,权值为该猪圈内猪的数量,之后前点连到后点权值INF。

2.客户取猪就是将他们所属的猪圈中能打开的猪圈与客户连INF边,客户向汇点连b权值的边。

3.之后将此时所有打开的猪圈的前状态与每个后状态都连INF边。

好的讲了一通是不是很简单……显然不能这么做,点太多了,O(跑不过)。

我们在拆完点之后还需要缩点:

1.如果几个结点的流量来源相同则可以合并

2.如果几个结点的流量去处相同则可以合并

3.如果两点间有INF的边,且到的点没有其他的流量来源,则可以可以合并

根据这些再画画图就能做啦!

对于新的图,我们构造的思想:

1.对于每一个用户,流入他所有能开开的猪圈的猪。

2.对于其他用户与前面的用户的猪圈有交集的,可以从他们那里“得到”猪。

参考了:https://www.cnblogs.com/sleeper-qp/archive/2012/07/23/2605253.html

//注意:此模板默认源点为1,汇点为m
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
const int INF=;
inline int read(){
int X=,w=;char ch=;
while(ch<''||ch>''){w|=ch=='-';ch=getchar();}
while(ch>=''&&ch<='')X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int next;
int to;
int w;
}edge[N*N*];
int head[N],cnt=-;
void add(int u,int v,int w){//u起点v终点w容量
cnt++;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
return;
}
int lev[N],cur[N];//lev层数,cur[i]为以i为起点的边的编号
bool bfs(int m){//强制1为源点,m为汇点
int dui[m],r=;//队列和右指针
for(int i=;i<=m;i++){//初始化
lev[i]=-;
cur[i]=head[i];
}
dui[]=,lev[]=;
int u,v;//u起点v终点
for(int l=;l<=r;l++){//左指针
u=dui[l];
for(int e=head[u];e!=-;e=edge[e].next){
v=edge[e].to;
if(edge[e].w>&&lev[v]==-){//1.能走 2.未分层
lev[v]=lev[u]+;
r++;
dui[r]=v;//v入队
if(v==m)return ;//分层完毕
}
}
}
return ;//无法分层
}
int dinic(int u,int flow,int m){//u当前点,flow为下面的点能够分配多大的流量,m终点
if(u==m)return flow;//终点直接全流入
int res=,delta;//res实际流量
for(int &e=cur[u];e!=-;e=edge[e].next){//'&'相当于cur[u]=e;即流满的边不会再被扫一次
int v=edge[e].to;
if(edge[e].w>&&lev[u]<lev[v]){//只能从低层往高层流
delta=dinic(v,min(edge[e].w,flow-res),m);
if(delta>){//如果增广
edge[e].w-=delta;//正向边容量减少
edge[e^].w+=delta;//反向边仍量增加(暗示退流)
res+=delta;//扩张流量增加
if(res==flow)break;//可流的都流完了,及时跳出
}
}
}
if(res!=flow)lev[u]=-;//没流完,说明以后不能从这个点流出任何流量,那就不需要这个点了
return res;
}
int num[];
int vis[];
int mp[N];
int main(){
int m=read();
int n=read();
int S=,T=n+;
memset(head,-,sizeof(head));
for(int i=;i<=m;i++)num[i]=read();
for(int i=;i<=n;i++){
int a=read();
for(int j=;j<=a;j++){
int p=read();
if(!vis[p]){
mp[i+]+=num[p];
vis[p]=i+;
}else{
add(vis[p],i+,INF);
add(i+,vis[p],);
}
}
int b=read();
add(i+,T,b);
add(T,i+,);
}
for(int i=;i<=n+;i++){
if(mp[i]){
add(S,i,mp[i]);
add(i,S,);
}
}
int ans=;
while(bfs(T))ans+=dinic(S,INF,T);
printf("%d\n",ans);
return ;
}

POJ1149:PIGS——题解的更多相关文章

  1. 题解 POJ1149 Pigs

    先翻译一下吧(题面可以在原OJ上找) Mirko在一个由M个锁着的猪舍组成的养猪场工作,Mirko无法解锁任何猪舍,因为他没有钥匙.客户纷纷来到农场.他们每个人都有一些猪舍的钥匙,并想购买一定数量的猪 ...

  2. POJ1149 PIGS 【最大流量】

    PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16555   Accepted: 7416 Description ...

  3. poj1149 PIGS 最大流(神奇的建图)

    一开始不看题解,建图出错了.后来发现是题目理解错了.  if Mirko wants, he can redistribute the remaining pigs across the unlock ...

  4. POJ1149 PIGS 【最大流 + 构图】

    题目链接:http://poj.org/problem?id=1149 PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions ...

  5. POJ1149 PIGS [最大流 建图]

    PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20662   Accepted: 9435 Description ...

  6. POJ1149 PIGS (网络流)

                                                                             PIGS Time Limit: 1000MS   M ...

  7. POJ1149 PIGS

    想了好久啊...(#-.-) 开始想到m*n个点的构图,明显超时,于是考虑压缩节点个数 我们发现每个猪圈最后被有且只有一个人调整,于是想到对于一个人,连接他能调整的每个猪圈的上一个控制人.(不懂可以开 ...

  8. POJ1149 PIGS(最大流)

    题意:       有一个人,他有m个猪圈,每个猪圈里面有一定数量的猪,但是每个猪圈的门都是锁着的,他自己没有钥匙,只有顾客有钥匙,一天依次来了n个顾客,(记住是依次来的)他们每个人都有一些钥匙,和他 ...

  9. poj图论解题报告索引

    最短路径: poj1125 - Stockbroker Grapevine(多源最短路径,floyd) poj1502 - MPI Maelstrom(单源最短路径,dijkstra,bellman- ...

随机推荐

  1. nexys4开发板使用-第一篇(未完成)

    1. 下去下个原理图.今天准备研究下DDR的控制,看介绍新一代的Nexys 4 DDR最值得被关注的改良是将原先的16 MiBCellularRAM升级为128 MiB的DDR2 SDRAM内存.Di ...

  2. JQuery.extend扩展实现同步post请求

    有时需要在jQuery中实现同步post请求,而jquery自带的是异步,需要通过JQuery.extend扩展. 支持ie和firefox,方法转载而来.需要在submit前将form.append ...

  3. 怎样安装JMeter

    JMeter有图形界面, 而且支持中文! JMeter官网地址: http://jmeter.apache.org/ 点击左上角的下载: 点击下面的.zip后缀的压缩包: 解压到本地: JMeter目 ...

  4. Siki_Unity_1-2_Unity5.2入门课程_进入Unity开发的奇幻世界_Roll A Ball

    1-2 Unity5.2入门课程 进入Unity开发的奇幻世界 任务1:Roll A Ball项目简介 Unity官网的tutorial入门项目 方向键控制小球在平台上滚动,碰撞方块得分,消掉所有方块 ...

  5. Memcached命令-存储命令-查找命令-清理命令

    Memcached set 存储命令 Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中. 如果set的key已经存在,该命令可以更新该key所对应的原来的数 ...

  6. 使用flume抓取tomcat的日志文件下沉到kafka消费

    Tomcat生产日志 Flume抓取日志下沉到kafka中 将写好的web项目打包成war包,eclise直接导出export,IDEA 在artifact中添加新的artifact-achieve项 ...

  7. Centos7下部署activeMQ消息队列服务

    #1.下载activeMQlinux包 http://activemq.apache.org/activemq-5100-release.html   下载linux的activeMQ包 #2.使用X ...

  8. LeetCode 445——两数相加 II

    1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...

  9. 1.EOS源码编译运行

    目前网络上都是针对老版EOS2.0源码编译的文章,我在mac上参考这些文章编译,最后发现根本就不对,最新版本只需一条命令(./eosio_build.sh,依赖库会自动安装的)即可.我根据这些文章手动 ...

  10. hive创建外部表

    Create [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment], ...)] ...