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. ToString的格式化字符串

    如下: , , ).ToString(@"d\.hh\:mm\:ss"); var b = DateTimeOffset.Now.ToString("yyyy-MM-dd ...

  2. 会声会影X10x9x8最新教程

    会声会影X10x9x8最新最全教程,全部都是干货,包含素材的,下载地址:百度网盘, https://pan.baidu.com/s/1AyVS-C_VcTEz_ir70u08xQ 以下为部分内容截图: ...

  3. 180608-Git工具之Stash

    git stash 暂存 背景: 实际开发过程中,经常可能遇到的一个问题,当你在dev分支上正开发得happy的时候:突然来了个线上bug,得赶紧从release分支上切一个bugfix分支来解决线上 ...

  4. Android开发-API指南-<permission>

    <permission> 英文原文:http://developer.android.com/guide/topics/manifest/permission-element.html 采 ...

  5. [Clr via C#读书笔记]Cp17委托

    Cp17委托 简单介绍 delegate回调函数机制,可以理解存储函数地址的变量类型: 类型安全: 引用类型支持逆变和协变: 回调 静态方法,实例方法 委托的本质 所有的委托都派生自System.Mu ...

  6. 正则表达式 和 re 模块

    正则表达式究竟是什么? 在一些网站注册的时候需要输入手机号码,当你输入一个错误的手机号码的时候,会提示你输入的手机号码格式错误 那么他究竟是如何判断的呢? 我们用Python代码进行表示: phone ...

  7. ubuntu server guide 学习笔记

    1. 软件包 1.1. dpkg dpkg -l dpkg -l | grep apache2 dpkg -L ufw dpkg -S /etc/host.conf dpkg -i zip_3.0-4 ...

  8. 水仙花数---基于python

    # coding:utf-8"""水仙花数是指一个 n 位数(n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153) ...

  9. QT界面绘制学习记录

    1. MVC结构中,model必须作为类的成员变量存在,不可再函数内部申明.否则,会出现函数调用结束,model找不到的错误. 2.QcomboBox可设置为左边空白,右侧一小箭头的形式.代码:com ...

  10. Acm hust 1.25

    闲着无聊做了点hust上 acm的训练题 A题 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=104738#problem/A 看了20分 ...