• 每个顾客分别用一个结点来表示。
• 对于每个猪圈的第一个顾客,从源点向他连一条边,容量就是该猪圈里的猪的初始数量。如果从源点到一名顾客有多条边,则可以把它们合并成一条,容量相加。
• 对于每个猪圈,假设有n个顾客打开过它,则对所有整数i∈[1, n),从该猪圈的第i个顾客向第i + 1个顾客连一条边,容量为∞。
• 从各个顾客到汇点各有一条边,容量是各个顾客能买的数量上限。
//768K 32MS G++ 1582B
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <map>
using namespace std;
int const MAX=110;
int const inf=0x3f3f3f3f;
int m[MAX][MAX], flow[MAX], front[MAX], visit[MAX],lock[MAX*10], node[MAX*10];
int S, T;
int M, N;
int bfs()
{
int u, i;
queue<int> Q;
while(!Q.empty()) Q.pop();
memset(visit, 0, sizeof visit);
memset(flow, 0, sizeof flow);
flow[S]=inf;
visit[S]=1;
Q.push(S);
while(!Q.empty())
{
u=Q.front();
Q.pop();
for(i=0; i<=T; i++)
{
if(!visit[i] && m[u][i]>0)
{
visit[i]=1;
Q.push(i);
front[i]=u;
flow[i]=m[u][i]<flow[u]?m[u][i]:flow[u];
}
}
}
return flow[T];
}
int EK()
{
int max_flow=0;
int u, f;
while((f=bfs())!=0)
{
for(u=T; u!=S; u=front[u])
{
m[front[u]][u]-=f;
m[u][front[u]]+=f;
}
max_flow+=f;
}
return max_flow;
}
int main()
{
#ifndef ONLINE_JUDGE
ifstream cin("in.txt");
#endif
int i, j, ans, num;
int u;
while(cin>>M>>N)
{
ans=0;
S=0;
T=N+1;
memset(m, 0, sizeof m);
memset(lock,0, sizeof lock);
for(i=1; i<=M; i++)
cin>>node[i];
for(i=1; i<=N; i++)
{
cin>>num;
for(j=1; j<=num; j++)
{
cin>>u;
if(lock[u]==0)
{
lock[u]=i;
m[S][i]+=node[u];
}
else
m[lock[u]][i]=inf;
}
cin>>m[i][T];
}
ans+=EK();
cout<<ans<<endl;
}
return 0;
}