描述 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 ;
}

最新文章

  1. iOS8.3发布了Swift 1.2带来哪些新变化
  2. Java NIO——2 缓冲区
  3. CodeForces 710E Generate a String
  4. hdu_5775_Bubble Sort(树状数组)
  5. 读Zepto源码之fx_methods模块
  6. 视觉SLAM的方案总结
  7. Solr 17 - Solr的时间为什么比本地少8小时 (附修改方法)
  8. 设计模式系列13:模板方法模式(Template Method Pattern)
  9. Vue基础知识
  10. 影响Arcmap运行效率的因素
  11. [DUBBO] Unexpected error occur at send statistic, cause: Forbid consumer 192.168.3.151 access servic
  12. Spring Security OAuth2 SSO 单点登录
  13. UBUNTU18.4环境下使用更好用的搜索引擎(无奈,只能起这样的标题)
  14. JNA调用DLL(入门):让你一眼就学会
  15. javascript 高级程序设计 四
  16. 开通博客啦 Let‘s Go!
  17. (IRCNN)Learning Deep CNN Denoiser Prior for Image Restoration-Kai Zhang
  18. [转载]如何解决failed to push some refs to git
  19. Ubuntu 14.04 64位上安装wps office软件(转http://m.blog.csdn.net/blog/yhc13429826359/24179933)
  20. Java集合--HashMap分析

热门文章

  1. jeakins忘记密码时的处理(简单粗暴)
  2. Centos/linux开放端口
  3. Ext中关于Ext.QuickTips.init()的使用
  4. json字符串数组判断其中
  5. 【bzoj2879】[Noi2012]美食节 费用流+动态加边
  6. 安装JDK以及配置Java运行环境
  7. GYM - 101147 B.Street
  8. POJ 2186 受欢迎的牛 Tarjan基础题
  9. Tomcat学习笔记(十二)
  10. hdu 1847 Good Luck in CET-4 Everybody! SG函数SG引理