Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 19900 | Accepted: 9103 |
Description
All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold.
More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses.
An unlimited number of pigs can be placed in every pig-house.
Write a program that will find the maximum number of pigs that he can sell on that day.
Input
The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000.
The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line):
A K1 K2 ... KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.
Output
Sample Input
3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6
Sample Output
7
Source
题目大意:有m个猪窝,有n个顾客,对于每一个顾客有想要买的猪窝的编号,对应有其钥匙 ,能够打开其猪窝随便挑选,然后给你每个人愿意购买的数量,如果一个顾客打开了多个猪窝,买完猪之后,可以对这些猪窝里边的猪数量进行随意分配,比如样例:
顾客一打开1、2猪窝之后,将剩余的猪全部放入2号猪窝之中,并买走两只猪。
顾客二打开1、3猪窝,将3号猪窝中买走三只猪。
顾客三打开2号猪窝,将其中两只猪买走。
2+3+2=7
思路:
首先庆祝一下又一道好题被我玷污了.......................
着重说一下如何建图:
1、首先要设定一个源点和汇点,将每一个顾客和汇点相连,然后将其设定权值为顾客想买的猪的数量。
2、我们处理完了顾客想买的猪的数量的边权问题,然后剩下的就是顾客能买的猪的数量的处理了。
①我们一共有m个猪窝,那么如果有边权重叠问题,我们其实可以使用相关拓展边来解决这个问题。
②我们按照样例来处理建图问题,首先我们将源点和顾客一连两条边,一条边权为猪窝1的猪数量,一条边权为猪窝2的猪数量,从而重叠在一起,相当于一条边,连入顾客1。
③然后我们将源点和顾客二连一条边,其权值为猪窝3的猪数量,那么猪窝1如何处理呢?我们从顾客一这个点连入顾客二这个点,一条值为INF的边,这样我们就可以处理重叠边的问题了。
④依次建图之后效果为这样:
3、建完图之后就是跑Dinic的程序了、
Ac代码:
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
int a[150000];
int head[100000];
struct EdgeNode
{
int to;
int w;
int next;
}e[1000000];
int pre[1000000];
int tmp[1000000];
int div[1000000];
int ss,tt,cont;
void add(int from,int to,int w)
{
e[cont].to=to;
e[cont].w=w;
e[cont].next=head[from];
head[from]=cont++;
}
int makediv()
{
memset(div,0,sizeof(div));
div[ss]=1;
queue<int >s;
s.push(ss);
while(!s.empty())
{
int u=s.front();
if(u==tt)return 1;
s.pop();
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
int w=e[i].w;
if(w&&div[v]==0)
{
div[v]=div[u]+1;
s.push(v);
}
}
}
return 0;
}
int Dfs(int u,int maxflow,int tt)
{
if(u==tt)return maxflow;
int ret=0;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
int w=e[i].w;
if(w&&div[v]==div[u]+1)
{
int f=Dfs(v,min(maxflow-ret,w),tt);
e[i].w-=f;
e[i^1].w+=f;
ret+=f;
if(ret==maxflow)return ret;
}
}
return ret;
}
int output;
int Dinic()
{
int ans=0;
while(makediv()==1)
{
ans+=Dfs(ss,INF,tt);
}
printf("%d\n",ans);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
ss=m+1;
tt=ss+1;
cont=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
int k;
scanf("%d",&k);
while(k--)
{
int v;
scanf("%d",&v);
if(pre[v]==0)
{
add(ss,i,a[v]);
add(i,ss,0);
}
else
{
add(pre[v],i,INF);
add(i,pre[v],0);
}
pre[v]=i;
}
int b;scanf("%d",&b);
add(i,tt,b);
add(tt,i,0);
}
Dinic();
}
}