描述 Description
尼克在一家养猪场工作,这家养猪场共有M间锁起来的猪舍,由于猪舍的钥匙都给了客户,所以尼克没有办法打开这些猪舍,客户们从早上开始一个接一个来购买生猪,他们到达后首先用手中的钥匙打开他所能打开的全部猪舍,然后从中选取他要买的生猪,尼克可以在此期间将打开的猪舍中的猪调整到其它开着的猪舍中,每个猪舍能存放的猪的数量是没有任何限制的。买完猪后客户会将他打开的猪舍关上。
好在尼克事先知道每位客户手中有哪些钥匙,要买多少猪,以及客户到来的先后次序。请你写一个程序,帮助尼克求出最多能卖出多少头生猪。
输入格式 Input Format
输入文件的第一行包含两个整数M和N,1≤M≤1000,1≤N≤100,M为猪舍的数量,N为客户人数,猪舍的编号为1到M,客户的编号为1到N。
输入文件第二行包含M个空格隔开的整数,依次表示每个猪舍中的生猪数量,每个整数大于等于0,且小于等于1000。
接下来的N行每行表示一位客户的购买信息,第I个客户的购买信息位于第I+2行,
其格式如下:
A K1 K2……KA B
它表示该客户共有A把钥匙,钥匙编号依次为K1 K2……KA,且K1<K2<……<KA,B为该客户要买的生猪的头数。
输出格式 Output Format
输出文件仅有一行包含一个整数,表示尼克最多能卖出的生猪的头数。
样例输入 Sample Input

3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6

样例输出 Sample Output

7
时间限制 Time Limitation
1s
注释 Hint
1s
来源 Source
poj 1149

  众所周知网络流难在建图。这道题我刚开始以为是源点连人【权值为需求数】,人连房间【权值为需求数】,房间汇点【是猪的个数】。然而建完图连手推样例都不行,GG。

  顺手翻了翻hzwer.com,然后就找到了,发现一个神犇的建图方法:

  1.每个顾客向汇点连接他的需求数

  2.对于每个猪圈,源点向第一个打开他的顾客连一条权值为猪数量的边

  3.每个顾客向下一个顾客连接一个权值为正无穷的边

  对于样例,我们可以建图:

  以顾客为点,如图所示

  【其中的4是猪圈1+2的和,因为他开了两个】最大流为7,符合样例

为什么这样建图?看题中所给的条件:每个顾客打开门后,尼克可以把猪迁移到开的房间。那么显然一个顾客对后面的顾客有影响。那么进入每个顾客的流量显然是这个顾客第一个打开的所有猪舍的和,这样向下一个顾客流,就相当于把猪的位置调换了。

AC代码:

#include<bits/stdc++.h>
#define ll long long
#define INF 2100000000
using std::min;
using std::cin;
using std::cout;
using std::endl; int n,m;
int q[];
int ans=;
int len=;
int s,t;
int level[];
int rev[];
int vis[];
int lin[];
int a[];
int ha=; struct qaq
{
int nt,y,v;
}e[]; char buf[<<],*fs,*ft;
inline char getc(){ return (fs==ft && (ft= (fs=buf) + fread(buf,,<<,stdin) , fs==ft) )?:*fs++; }
int read()
{
char ch=getc();int k=,f=;
while(!isdigit(ch)) { if(ch=='-') f=-; ch=getc(); }
while(isdigit(ch)) { k=(k<<)+(k<<)+ch-''; ch=getc(); }
return k*f;
} void insert(int x,int y,int v)
{
e[++len].nt=lin[x]; lin[x]=len; e[len].v=v; e[len].y=y; rev[len]=len+;
e[++len].nt=lin[y]; lin[y]=len; e[len].v=; e[len].y=x; rev[len]=len-;
} bool make_level()
{
int head=,tail=;
q[]=s;
memset(level,-,sizeof(level));
level[s]=;
while(head<tail)
{
int x=q[++head];
for(int i=lin[x];i;i=e[i].nt)
{
if(e[i].v && level[e[i].y]==-)
{
level[e[i].y]=level[x]+;
q[++tail]=e[i].y;
}
}
}
return level[t]>=;
} int max_flow(int k,int flow)
{
if(k==t) return flow;
int maxflow=;
int v;
for(int i=lin[k];i && maxflow<flow;i=e[i].nt)
if(e[i].v && level[e[i].y]==level[k]+)
if(v=max_flow(e[i].y,min(e[i].v,flow-maxflow)))
maxflow+=v , e[i].v-=v , e[rev[i]].v+=v;
if(!maxflow) level[k]=-;
return maxflow;
} void dinic()
{
int v;
while(make_level())
while(v=max_flow(s,INF))
ans+=v;
} int main()
{
//freopen("a.txt","r",stdin);
m=read();n=read();//m is pig
//cout<<n<<' '<<m<<endl;
memset(vis,,sizeof(vis));
s=;
t=n+;
for(int i=;i<=m;i++) a[i]=read();
for(int i=;i<=n;++i)
{
int key=read();
for(int j=;j<=key;++j)
{
int val=read();
if(!vis[val]) insert(s,i,a[val]);
else insert(vis[val],i,INF);
vis[val]=i;
}
key=read();
insert(i,t,key);
}
//cout<<12357<<endl;
dinic();
printf("%d\n",ans);
return ;
}

【poj1149】 pigs 网络流最大流问题的更多相关文章

  1. POJ1149 PIGS (网络流)

                                                                             PIGS Time Limit: 1000MS   M ...

  2. poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新

    题目大意:是有M个猪圈,N个顾客,顾客要买猪,神奇的是顾客有一些猪圈的钥匙而主人MIRKO却没有钥匙,多么神奇?顾客可以在打开的猪圈购买任意数量的猪,只要猪圈里有足够数量的猪.而且当顾客打开猪圈后mi ...

  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. POJ 1149:PIGS 网络流经典题

    PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18345   Accepted: 8354 Description ...

  6. POJ1149 PIGS [最大流 建图]

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

  7. POJ1149 PIGS

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

  8. POJ1149 PIGS 【最大流量】

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

  9. BZOJ1280 Emmy卖猪pigs 网络流

    正解:网络流 解题报告: 传送门! 我网络流的基础题都还麻油做完就来做这个了,,,wsl,,, 首先想下最基础的构图方法 不难想到把猪圈和顾客分别当做节点,然后新建一个源点和汇点 然后考虑怎么连边,首 ...

随机推荐

  1. JMeter学习笔记(三) 录制脚本

    jmeter测试脚本,可以通过其他工具进行录制,例如 BadBoy,我之前使用过此工具,安装以及使用都比较简单的,大家可以在网上搜索一下. 在此整理一下jmeter自带的录制功能,进行录制脚本. 1. ...

  2. python 3 使用cmp函数报错

    python3 中已经不使用cmp函数进行比较大小,使用operator模块 import operator lt(a,b) 相当于 a<b 从第一个数字或字母(ASCII)比大小 le(a,b ...

  3. MySQL数据库有哪些特点

    MySQL数据库的特点有: 它是C和C++语言编写的.支持多个操作系统.支持多线程.为多种编程语言提供API.优化SQL算法提高了查询速度以及提供用于管理和检查数据库的管理工具 MySQL数据库 My ...

  4. JavaWeb笔记(三)HTTP

    常见请求头 User-Agent:浏览器版本信息,可以解决浏览器兼容性问题 Referer:请求来源地址,可以防盗链和统计 Request 方法 获取请求方式: String getMethod() ...

  5. 历届试题 带分数 全排列模板 JAVA

    标题:带分数 100 可以表示为带分数的形式:100 = 3 + 69258 / 714 还可以表示为:100 = 82 + 3546 / 197 注意特征:带分数中,数字1~9分别出现且只出现一次( ...

  6. # Including Artificial Intelligence in a Routing ProtocolUsing Software Defined Networks

    Abstract: 问题:AI在路由协议上的应用仅适用于真实设备,尤其是无线传感器节点 The inclusion of artificial intelligence (AI) can improv ...

  7. PHP面向对象 封装与继承

    知识点: PHP封装三个关键词: 一.public 公有的,被public修饰的属性和方法,对象可以任意访问和调用 二.private 私有的,被private修饰的属性和方法,只能在类内部的方法可以 ...

  8. 简单的FreeBSD 的内核编译

    简单的FreeBSD 的内核编译 删除并重新下载内核源码 删除自带的内核源码rm -rf /usr/src 下载内核源码wget https://download.freebsd.org/ftp/re ...

  9. Hash表模板

    namespace Hash { ; ; struct adj { ll nxt,v,num,val; }e[N]; ll head[H],ecnt=; void init() { ecnt=; me ...

  10. JavaScript中继承机制的模仿实现

    首先,我们用一个经典例子来简单阐述一下ECMAScript中的继承机制. 在几何学上,实质上几何形状只有两种,即椭圆形(是圆形的)和多边形(具有一定数量的边).圆是椭圆的一种,它只有一个焦点.三角形. ...