1280: Emmy卖猪pigs
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 186 Solved: 126
[ Submit][ Status][ Discuss]
Description
Emmy在一个养猪场工作。这个养猪场有M个锁着的猪圈,但Emmy并没有钥匙。顾客会到养猪场来买猪,一个接着一个。每一位顾客都会有一些猪圈的钥匙,他们会将这些猪圈打开并买走固定数目的猪。 所有顾客有的钥匙和他们需要买猪的数量在事先都告诉了Emmy,于是Emmy要订一个计划,使得卖出去的猪最多。 买卖的过程是这样的:一个顾客前来,并打开所有他可以打开的猪圈。然后Emmy从这些猪圈里牵出固定数目的猪卖给顾客(最多只能和顾客需要数相等),并可以重新安排这些开着的猪圈中的猪。 每个猪圈可以存放任意数目的猪。 写一个程序,使得Emmy能够卖出去尽可能多的猪。
Input
第一行有两个整数:M和N,表示猪圈数和顾客数。 第二行有M个整数,表示每个猪圈初始时有多少猪。 接下来的N行按照前来的次序描述了每一个顾客,每行的格式如下: A K1 K2…KA B A表示该顾客拥有的钥匙数,K1...KA表示每个钥匙所对应的猪圈,B表示该顾客需要购买的猪的数目。
Output
仅包含一个整数,即最多能卖出去的猪的数目。
Sample Input
3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6
3 1 10
2 1 2 2
2 1 3 3
1 2 6
Sample Output
7
HINT
1 ≤ M ≤ 1000
1 ≤ N ≤ 100
Source
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1202;
const int maxm = 2E5 + 2E3 + 20;
typedef long long LL;
const LL INF = 1E16;
struct E{
int to; LL cap,flow; E(){}
E(int to,LL cap,LL flow): to(to),cap(cap),flow(flow){}
}edgs[maxm];
int n,m,cnt,s,t,L[maxn],cur[maxn],stk[maxn],st[maxn],vis[maxn],vis2[maxn];
bool bo[maxn][maxn];
vector <int> v[maxn],G[maxn];
queue <int> Q;
void Add(int x,int y,LL cap)
{
v[x].push_back(cnt); edgs[cnt++] = E(y,cap,0);
v[y].push_back(cnt); edgs[cnt++] = E(x,0,0);
}
bool BFS()
{
for (int i = s; i <= t; i++) L[i] = 0;
L[s] = 1; Q.push(s);
while (!Q.empty())
{
int k = Q.front(); Q.pop();
for (int i = 0; i < v[k].size(); i++)
{
E e = edgs[v[k][i]];
if (e.cap == e.flow || L[e.to]) continue;
L[e.to] = L[k] + 1; Q.push(e.to);
}
}
return L[t];
}
LL Dinic(int x,LL a)
{
if (x == t) return a; LL flow = 0;
for (int &i = cur[x]; i < v[x].size(); i++)
{
E &e = edgs[v[x][i]];
if (e.cap == e.flow || L[e.to] != L[x] + 1) continue;
LL f = Dinic(e.to,min(a,e.cap - e.flow));
if (!f) continue; flow += f; e.flow += f;
edgs[v[x][i]^1].flow -= f; a -= f;
if (!a) return flow;
}
if (!flow) L[x] = -1; return flow;
}
LL getLL()
{
char ch = getchar(); LL ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret * 10LL + 1LL * (ch - '0'),ch = getchar();
return ret;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
m = getLL(); n = getLL(); t = m + n + 1;
for (int i = 1; i <= m; i++) Add(i,t,getLL());
for (int i = 1; i <= n; i++)
{
int k = getLL(),tp = 0;
for (int j = 1; j <= k; j++)
{
int A; A = stk[j] = getLL();
if (vis[A] != i) vis[A] = i,Add(i + m,A,INF);
for (int l = 0; l < G[A].size(); l++)
{
int B = G[A][l];
if (vis[B] != i) vis[B] = i,Add(i + m,B,INF);
if (vis2[B] != i) vis2[B] = i,st[++tp] = B;
}
}
Add(s,i + m,getLL()); if (!k) continue;
for (int j = 1; j <= k; j++)
{
int A = stk[j];
for (int l = j + 1; l <= k; l++)
{
int B = stk[l];
if (!bo[A][B]) bo[A][B] = 1,G[A].push_back(B);
if (!bo[B][A]) bo[B][A] = 1,G[B].push_back(A);
}
for (int l = 1; l <= tp; l++)
if (st[l] != A && !bo[A][st[l]])
bo[A][st[l]] = 1,G[A].push_back(st[l]);
}
}
LL MaxFlow = 0;
while (BFS())
{
for (int i = s; i <= t; i++) cur[i] = 0;
MaxFlow += Dinic(s,INF);
}
cout << MaxFlow << endl;
return 0;
}