这题很简单啊…因为很接近模板
不会最大全闭合子图的先去学习…(当然下面我也是从0讲起,不过不一定能看懂)
现在商品间还有依赖关系
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
#define int long long
const int inf=1e14;
int n,m,s,t,sumn,a[maxn],b[maxn],x[5009][5009],dis[maxn];
struct edge{
int to,nxt,flow;
}d[maxn]; int head[maxn],cnt=1;
void add(int u,int v,int flow){
d[++cnt]=(edge){v,head[u],flow},head[u]=cnt;
d[++cnt]=(edge){u,head[v],0},head[v]=cnt;
}
bool bfs()
{
for(int i=1;i<=t;i++) dis[i]=0;
dis[s]=1;
queue<int>q; q.push( s );
while( !q.empty() )
{
int u=q.front(); q.pop();
for(int i=head[u];i;i=d[i].nxt )
{
int v=d[i].to;
if( d[i].flow&&dis[v]==0 )
{
dis[v]=dis[u]+1;
if( v==t ) return true;
q.push( v );
}
}
}
return false;
}
int dinic(int u,int flow)
{
if( u==t ) return flow;
int res=flow;
for(int i=head[u];i&&res;i=d[i].nxt )
{
int v=d[i].to;
if( dis[v]==dis[u]+1&&d[i].flow)
{
int temp=dinic(v,min(res,d[i].flow) );
if( temp==0 ) dis[v]=0;
res-=temp;
d[i].flow-=temp;
d[i^1].flow+=temp;
}
}
return flow-res;
}
signed main()
{
int T; cin >> T;
while( T-- )
{
cin >> n >> m;
s=0,t=n+m+1;
cnt=1;
for(int i=s;i<=t;i++) head[i]=0;
for(int i=1;i<=n;i++)
{
int x; cin >> x;
sumn+=x;
add(s,i,x);
}
for(int i=1;i<=m;i++)
{
int x; cin >> x;
add(i+n,t,x);
}
for(int i=1;i<=n;i++)
{
int q,w; cin >> q >> w;
while( q-- )
{
int x; cin >> x;//这是矿石
add(i,x+n,inf);
}
while( w-- )
{
int x; cin >> x;
add( i,x,inf );
}
}
while( bfs() ) sumn-=dinic(s,inf);
cout << sumn << endl;
sumn=0;
}
}